1 //===-- Debugger.cpp --------------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "lldb/lldb-private.h" 11 #include "lldb/Core/ConnectionFileDescriptor.h" 12 #include "lldb/Core/Debugger.h" 13 #include "lldb/Core/InputReader.h" 14 #include "lldb/Core/State.h" 15 #include "lldb/Core/StreamString.h" 16 #include "lldb/Core/Timer.h" 17 #include "lldb/Host/Terminal.h" 18 #include "lldb/Interpreter/CommandInterpreter.h" 19 #include "lldb/Target/TargetList.h" 20 #include "lldb/Target/Process.h" 21 #include "lldb/Target/RegisterContext.h" 22 #include "lldb/Target/StopInfo.h" 23 #include "lldb/Target/Thread.h" 24 25 26 using namespace lldb; 27 using namespace lldb_private; 28 29 30 static uint32_t g_shared_debugger_refcount = 0; 31 static lldb::user_id_t g_unique_id = 1; 32 33 #pragma mark Static Functions 34 35 static Mutex & 36 GetDebuggerListMutex () 37 { 38 static Mutex g_mutex(Mutex::eMutexTypeRecursive); 39 return g_mutex; 40 } 41 42 typedef std::vector<DebuggerSP> DebuggerList; 43 44 static DebuggerList & 45 GetDebuggerList() 46 { 47 // hide the static debugger list inside a singleton accessor to avoid 48 // global init contructors 49 static DebuggerList g_list; 50 return g_list; 51 } 52 53 54 #pragma mark Debugger 55 56 UserSettingsControllerSP & 57 Debugger::GetSettingsController () 58 { 59 static UserSettingsControllerSP g_settings_controller; 60 return g_settings_controller; 61 } 62 63 int 64 Debugger::TestDebuggerRefCount () 65 { 66 return g_shared_debugger_refcount; 67 } 68 69 void 70 Debugger::Initialize () 71 { 72 if (g_shared_debugger_refcount == 0) 73 { 74 lldb_private::Initialize(); 75 } 76 g_shared_debugger_refcount++; 77 78 } 79 80 void 81 Debugger::Terminate () 82 { 83 if (g_shared_debugger_refcount > 0) 84 { 85 g_shared_debugger_refcount--; 86 if (g_shared_debugger_refcount == 0) 87 { 88 lldb_private::WillTerminate(); 89 lldb_private::Terminate(); 90 91 // Clear our master list of debugger objects 92 Mutex::Locker locker (GetDebuggerListMutex ()); 93 GetDebuggerList().clear(); 94 } 95 } 96 } 97 98 void 99 Debugger::SettingsInitialize () 100 { 101 static bool g_initialized = false; 102 103 if (!g_initialized) 104 { 105 g_initialized = true; 106 UserSettingsControllerSP &usc = GetSettingsController(); 107 usc.reset (new SettingsController); 108 UserSettingsController::InitializeSettingsController (usc, 109 SettingsController::global_settings_table, 110 SettingsController::instance_settings_table); 111 // Now call SettingsInitialize for each settings 'child' of Debugger 112 Target::SettingsInitialize (); 113 } 114 } 115 116 void 117 Debugger::SettingsTerminate () 118 { 119 120 // Must call SettingsTerminate() for each settings 'child' of Debugger, before terminating the Debugger's 121 // Settings. 122 123 Target::SettingsTerminate (); 124 125 // Now terminate the Debugger Settings. 126 127 UserSettingsControllerSP &usc = GetSettingsController(); 128 UserSettingsController::FinalizeSettingsController (usc); 129 usc.reset(); 130 } 131 132 DebuggerSP 133 Debugger::CreateInstance () 134 { 135 DebuggerSP debugger_sp (new Debugger); 136 // Scope for locker 137 { 138 Mutex::Locker locker (GetDebuggerListMutex ()); 139 GetDebuggerList().push_back(debugger_sp); 140 } 141 return debugger_sp; 142 } 143 144 void 145 Debugger::Destroy (lldb::DebuggerSP &debugger_sp) 146 { 147 if (debugger_sp.get() == NULL) 148 return; 149 150 Mutex::Locker locker (GetDebuggerListMutex ()); 151 DebuggerList &debugger_list = GetDebuggerList (); 152 DebuggerList::iterator pos, end = debugger_list.end(); 153 for (pos = debugger_list.begin (); pos != end; ++pos) 154 { 155 if ((*pos).get() == debugger_sp.get()) 156 { 157 debugger_list.erase (pos); 158 return; 159 } 160 } 161 162 } 163 164 lldb::DebuggerSP 165 Debugger::GetSP () 166 { 167 lldb::DebuggerSP debugger_sp; 168 169 Mutex::Locker locker (GetDebuggerListMutex ()); 170 DebuggerList &debugger_list = GetDebuggerList(); 171 DebuggerList::iterator pos, end = debugger_list.end(); 172 for (pos = debugger_list.begin(); pos != end; ++pos) 173 { 174 if ((*pos).get() == this) 175 { 176 debugger_sp = *pos; 177 break; 178 } 179 } 180 return debugger_sp; 181 } 182 183 lldb::DebuggerSP 184 Debugger::FindDebuggerWithInstanceName (const ConstString &instance_name) 185 { 186 lldb::DebuggerSP debugger_sp; 187 188 Mutex::Locker locker (GetDebuggerListMutex ()); 189 DebuggerList &debugger_list = GetDebuggerList(); 190 DebuggerList::iterator pos, end = debugger_list.end(); 191 192 for (pos = debugger_list.begin(); pos != end; ++pos) 193 { 194 if ((*pos).get()->m_instance_name == instance_name) 195 { 196 debugger_sp = *pos; 197 break; 198 } 199 } 200 return debugger_sp; 201 } 202 203 TargetSP 204 Debugger::FindTargetWithProcessID (lldb::pid_t pid) 205 { 206 lldb::TargetSP target_sp; 207 Mutex::Locker locker (GetDebuggerListMutex ()); 208 DebuggerList &debugger_list = GetDebuggerList(); 209 DebuggerList::iterator pos, end = debugger_list.end(); 210 for (pos = debugger_list.begin(); pos != end; ++pos) 211 { 212 target_sp = (*pos)->GetTargetList().FindTargetWithProcessID (pid); 213 if (target_sp) 214 break; 215 } 216 return target_sp; 217 } 218 219 220 Debugger::Debugger () : 221 UserID (g_unique_id++), 222 DebuggerInstanceSettings (*GetSettingsController()), 223 m_input_comm("debugger.input"), 224 m_input_file (), 225 m_output_file (), 226 m_error_file (), 227 m_target_list (), 228 m_platform_list (), 229 m_listener ("lldb.Debugger"), 230 m_source_manager (), 231 m_command_interpreter_ap (new CommandInterpreter (*this, eScriptLanguageDefault, false)), 232 m_input_readers (), 233 m_input_reader_data () 234 { 235 m_input_comm.SetCloseOnEOF(false); 236 m_command_interpreter_ap->Initialize (); 237 // Always add our default platform to the platform list 238 PlatformSP default_platform_sp (Platform::GetDefaultPlatform()); 239 assert (default_platform_sp.get()); 240 m_platform_list.Append (default_platform_sp, true); 241 } 242 243 Debugger::~Debugger () 244 { 245 CleanUpInputReaders(); 246 int num_targets = m_target_list.GetNumTargets(); 247 for (int i = 0; i < num_targets; i++) 248 { 249 ProcessSP process_sp (m_target_list.GetTargetAtIndex (i)->GetProcessSP()); 250 if (process_sp) 251 process_sp->Destroy(); 252 } 253 DisconnectInput(); 254 } 255 256 257 bool 258 Debugger::GetAsyncExecution () 259 { 260 return !m_command_interpreter_ap->GetSynchronous(); 261 } 262 263 void 264 Debugger::SetAsyncExecution (bool async_execution) 265 { 266 m_command_interpreter_ap->SetSynchronous (!async_execution); 267 } 268 269 270 void 271 Debugger::SetInputFileHandle (FILE *fh, bool tranfer_ownership) 272 { 273 File &in_file = GetInputFile(); 274 in_file.SetStream (fh, tranfer_ownership); 275 if (in_file.IsValid() == false) 276 in_file.SetStream (stdin, true); 277 278 // Disconnect from any old connection if we had one 279 m_input_comm.Disconnect (); 280 m_input_comm.SetConnection (new ConnectionFileDescriptor (in_file.GetDescriptor(), true)); 281 m_input_comm.SetReadThreadBytesReceivedCallback (Debugger::DispatchInputCallback, this); 282 283 Error error; 284 if (m_input_comm.StartReadThread (&error) == false) 285 { 286 File &err_file = GetErrorFile(); 287 288 err_file.Printf ("error: failed to main input read thread: %s", error.AsCString() ? error.AsCString() : "unkown error"); 289 exit(1); 290 } 291 } 292 293 void 294 Debugger::SetOutputFileHandle (FILE *fh, bool tranfer_ownership) 295 { 296 File &out_file = GetOutputFile(); 297 out_file.SetStream (fh, tranfer_ownership); 298 if (out_file.IsValid() == false) 299 out_file.SetStream (stdout, false); 300 301 GetCommandInterpreter().GetScriptInterpreter()->ResetOutputFileHandle (fh); 302 } 303 304 void 305 Debugger::SetErrorFileHandle (FILE *fh, bool tranfer_ownership) 306 { 307 File &err_file = GetErrorFile(); 308 err_file.SetStream (fh, tranfer_ownership); 309 if (err_file.IsValid() == false) 310 err_file.SetStream (stderr, false); 311 } 312 313 ExecutionContext 314 Debugger::GetSelectedExecutionContext () 315 { 316 ExecutionContext exe_ctx; 317 exe_ctx.Clear(); 318 319 lldb::TargetSP target_sp = GetSelectedTarget(); 320 exe_ctx.target = target_sp.get(); 321 322 if (target_sp) 323 { 324 exe_ctx.process = target_sp->GetProcessSP().get(); 325 if (exe_ctx.process && exe_ctx.process->IsRunning() == false) 326 { 327 exe_ctx.thread = exe_ctx.process->GetThreadList().GetSelectedThread().get(); 328 if (exe_ctx.thread == NULL) 329 exe_ctx.thread = exe_ctx.process->GetThreadList().GetThreadAtIndex(0).get(); 330 if (exe_ctx.thread) 331 { 332 exe_ctx.frame = exe_ctx.thread->GetSelectedFrame().get(); 333 if (exe_ctx.frame == NULL) 334 exe_ctx.frame = exe_ctx.thread->GetStackFrameAtIndex (0).get(); 335 } 336 } 337 } 338 return exe_ctx; 339 340 } 341 342 InputReaderSP 343 Debugger::GetCurrentInputReader () 344 { 345 InputReaderSP reader_sp; 346 347 if (!m_input_readers.empty()) 348 { 349 // Clear any finished readers from the stack 350 while (CheckIfTopInputReaderIsDone()) ; 351 352 if (!m_input_readers.empty()) 353 reader_sp = m_input_readers.top(); 354 } 355 356 return reader_sp; 357 } 358 359 void 360 Debugger::DispatchInputCallback (void *baton, const void *bytes, size_t bytes_len) 361 { 362 if (bytes_len > 0) 363 ((Debugger *)baton)->DispatchInput ((char *)bytes, bytes_len); 364 else 365 ((Debugger *)baton)->DispatchInputEndOfFile (); 366 } 367 368 369 void 370 Debugger::DispatchInput (const char *bytes, size_t bytes_len) 371 { 372 if (bytes == NULL || bytes_len == 0) 373 return; 374 375 WriteToDefaultReader (bytes, bytes_len); 376 } 377 378 void 379 Debugger::DispatchInputInterrupt () 380 { 381 m_input_reader_data.clear(); 382 383 InputReaderSP reader_sp (GetCurrentInputReader ()); 384 if (reader_sp) 385 { 386 reader_sp->Notify (eInputReaderInterrupt); 387 388 // If notifying the reader of the interrupt finished the reader, we should pop it off the stack. 389 while (CheckIfTopInputReaderIsDone ()) ; 390 } 391 } 392 393 void 394 Debugger::DispatchInputEndOfFile () 395 { 396 m_input_reader_data.clear(); 397 398 InputReaderSP reader_sp (GetCurrentInputReader ()); 399 if (reader_sp) 400 { 401 reader_sp->Notify (eInputReaderEndOfFile); 402 403 // If notifying the reader of the end-of-file finished the reader, we should pop it off the stack. 404 while (CheckIfTopInputReaderIsDone ()) ; 405 } 406 } 407 408 void 409 Debugger::CleanUpInputReaders () 410 { 411 m_input_reader_data.clear(); 412 413 // The bottom input reader should be the main debugger input reader. We do not want to close that one here. 414 while (m_input_readers.size() > 1) 415 { 416 InputReaderSP reader_sp (GetCurrentInputReader ()); 417 if (reader_sp) 418 { 419 reader_sp->Notify (eInputReaderEndOfFile); 420 reader_sp->SetIsDone (true); 421 } 422 } 423 } 424 425 void 426 Debugger::NotifyTopInputReader (InputReaderAction notification) 427 { 428 InputReaderSP reader_sp (GetCurrentInputReader()); 429 if (reader_sp) 430 { 431 reader_sp->Notify (notification); 432 433 // Flush out any input readers that are done. 434 while (CheckIfTopInputReaderIsDone ()) 435 /* Do nothing. */; 436 } 437 } 438 439 void 440 Debugger::WriteToDefaultReader (const char *bytes, size_t bytes_len) 441 { 442 if (bytes && bytes_len) 443 m_input_reader_data.append (bytes, bytes_len); 444 445 if (m_input_reader_data.empty()) 446 return; 447 448 while (!m_input_readers.empty() && !m_input_reader_data.empty()) 449 { 450 // Get the input reader from the top of the stack 451 InputReaderSP reader_sp (GetCurrentInputReader ()); 452 if (!reader_sp) 453 break; 454 455 size_t bytes_handled = reader_sp->HandleRawBytes (m_input_reader_data.c_str(), 456 m_input_reader_data.size()); 457 if (bytes_handled) 458 { 459 m_input_reader_data.erase (0, bytes_handled); 460 } 461 else 462 { 463 // No bytes were handled, we might not have reached our 464 // granularity, just return and wait for more data 465 break; 466 } 467 } 468 469 // Flush out any input readers that are done. 470 while (CheckIfTopInputReaderIsDone ()) 471 /* Do nothing. */; 472 473 } 474 475 void 476 Debugger::PushInputReader (const InputReaderSP& reader_sp) 477 { 478 if (!reader_sp) 479 return; 480 481 // Deactivate the old top reader 482 InputReaderSP top_reader_sp (GetCurrentInputReader ()); 483 484 if (top_reader_sp) 485 top_reader_sp->Notify (eInputReaderDeactivate); 486 487 m_input_readers.push (reader_sp); 488 reader_sp->Notify (eInputReaderActivate); 489 ActivateInputReader (reader_sp); 490 } 491 492 bool 493 Debugger::PopInputReader (const lldb::InputReaderSP& pop_reader_sp) 494 { 495 bool result = false; 496 497 // The reader on the stop of the stack is done, so let the next 498 // read on the stack referesh its prompt and if there is one... 499 if (!m_input_readers.empty()) 500 { 501 // Cannot call GetCurrentInputReader here, as that would cause an infinite loop. 502 InputReaderSP reader_sp(m_input_readers.top()); 503 504 if (!pop_reader_sp || pop_reader_sp.get() == reader_sp.get()) 505 { 506 m_input_readers.pop (); 507 reader_sp->Notify (eInputReaderDeactivate); 508 reader_sp->Notify (eInputReaderDone); 509 result = true; 510 511 if (!m_input_readers.empty()) 512 { 513 reader_sp = m_input_readers.top(); 514 if (reader_sp) 515 { 516 ActivateInputReader (reader_sp); 517 reader_sp->Notify (eInputReaderReactivate); 518 } 519 } 520 } 521 } 522 return result; 523 } 524 525 bool 526 Debugger::CheckIfTopInputReaderIsDone () 527 { 528 bool result = false; 529 if (!m_input_readers.empty()) 530 { 531 // Cannot call GetCurrentInputReader here, as that would cause an infinite loop. 532 InputReaderSP reader_sp(m_input_readers.top()); 533 534 if (reader_sp && reader_sp->IsDone()) 535 { 536 result = true; 537 PopInputReader (reader_sp); 538 } 539 } 540 return result; 541 } 542 543 void 544 Debugger::ActivateInputReader (const InputReaderSP &reader_sp) 545 { 546 int input_fd = m_input_file.GetFile().GetDescriptor(); 547 548 if (input_fd >= 0) 549 { 550 Terminal tty(input_fd); 551 552 tty.SetEcho(reader_sp->GetEcho()); 553 554 switch (reader_sp->GetGranularity()) 555 { 556 case eInputReaderGranularityByte: 557 case eInputReaderGranularityWord: 558 tty.SetCanonical (false); 559 break; 560 561 case eInputReaderGranularityLine: 562 case eInputReaderGranularityAll: 563 tty.SetCanonical (true); 564 break; 565 566 default: 567 break; 568 } 569 } 570 } 571 572 DebuggerSP 573 Debugger::FindDebuggerWithID (lldb::user_id_t id) 574 { 575 lldb::DebuggerSP debugger_sp; 576 577 Mutex::Locker locker (GetDebuggerListMutex ()); 578 DebuggerList &debugger_list = GetDebuggerList(); 579 DebuggerList::iterator pos, end = debugger_list.end(); 580 for (pos = debugger_list.begin(); pos != end; ++pos) 581 { 582 if ((*pos).get()->GetID() == id) 583 { 584 debugger_sp = *pos; 585 break; 586 } 587 } 588 return debugger_sp; 589 } 590 591 static void 592 TestPromptFormats (StackFrame *frame) 593 { 594 if (frame == NULL) 595 return; 596 597 StreamString s; 598 const char *prompt_format = 599 "{addr = '${addr}'\n}" 600 "{process.id = '${process.id}'\n}" 601 "{process.name = '${process.name}'\n}" 602 "{process.file.basename = '${process.file.basename}'\n}" 603 "{process.file.fullpath = '${process.file.fullpath}'\n}" 604 "{thread.id = '${thread.id}'\n}" 605 "{thread.index = '${thread.index}'\n}" 606 "{thread.name = '${thread.name}'\n}" 607 "{thread.queue = '${thread.queue}'\n}" 608 "{thread.stop-reason = '${thread.stop-reason}'\n}" 609 "{target.arch = '${target.arch}'\n}" 610 "{module.file.basename = '${module.file.basename}'\n}" 611 "{module.file.fullpath = '${module.file.fullpath}'\n}" 612 "{file.basename = '${file.basename}'\n}" 613 "{file.fullpath = '${file.fullpath}'\n}" 614 "{frame.index = '${frame.index}'\n}" 615 "{frame.pc = '${frame.pc}'\n}" 616 "{frame.sp = '${frame.sp}'\n}" 617 "{frame.fp = '${frame.fp}'\n}" 618 "{frame.flags = '${frame.flags}'\n}" 619 "{frame.reg.rdi = '${frame.reg.rdi}'\n}" 620 "{frame.reg.rip = '${frame.reg.rip}'\n}" 621 "{frame.reg.rsp = '${frame.reg.rsp}'\n}" 622 "{frame.reg.rbp = '${frame.reg.rbp}'\n}" 623 "{frame.reg.rflags = '${frame.reg.rflags}'\n}" 624 "{frame.reg.xmm0 = '${frame.reg.xmm0}'\n}" 625 "{frame.reg.carp = '${frame.reg.carp}'\n}" 626 "{function.id = '${function.id}'\n}" 627 "{function.name = '${function.name}'\n}" 628 "{function.addr-offset = '${function.addr-offset}'\n}" 629 "{function.line-offset = '${function.line-offset}'\n}" 630 "{function.pc-offset = '${function.pc-offset}'\n}" 631 "{line.file.basename = '${line.file.basename}'\n}" 632 "{line.file.fullpath = '${line.file.fullpath}'\n}" 633 "{line.number = '${line.number}'\n}" 634 "{line.start-addr = '${line.start-addr}'\n}" 635 "{line.end-addr = '${line.end-addr}'\n}" 636 ; 637 638 SymbolContext sc (frame->GetSymbolContext(eSymbolContextEverything)); 639 ExecutionContext exe_ctx; 640 frame->CalculateExecutionContext(exe_ctx); 641 const char *end = NULL; 642 if (Debugger::FormatPrompt (prompt_format, &sc, &exe_ctx, &sc.line_entry.range.GetBaseAddress(), s, &end)) 643 { 644 printf("%s\n", s.GetData()); 645 } 646 else 647 { 648 printf ("error: at '%s'\n", end); 649 printf ("what we got: %s\n", s.GetData()); 650 } 651 } 652 653 bool 654 Debugger::FormatPrompt 655 ( 656 const char *format, 657 const SymbolContext *sc, 658 const ExecutionContext *exe_ctx, 659 const Address *addr, 660 Stream &s, 661 const char **end 662 ) 663 { 664 bool success = true; 665 const char *p; 666 for (p = format; *p != '\0'; ++p) 667 { 668 size_t non_special_chars = ::strcspn (p, "${}\\"); 669 if (non_special_chars > 0) 670 { 671 if (success) 672 s.Write (p, non_special_chars); 673 p += non_special_chars; 674 } 675 676 if (*p == '\0') 677 { 678 break; 679 } 680 else if (*p == '{') 681 { 682 // Start a new scope that must have everything it needs if it is to 683 // to make it into the final output stream "s". If you want to make 684 // a format that only prints out the function or symbol name if there 685 // is one in the symbol context you can use: 686 // "{function =${function.name}}" 687 // The first '{' starts a new scope that end with the matching '}' at 688 // the end of the string. The contents "function =${function.name}" 689 // will then be evaluated and only be output if there is a function 690 // or symbol with a valid name. 691 StreamString sub_strm; 692 693 ++p; // Skip the '{' 694 695 if (FormatPrompt (p, sc, exe_ctx, addr, sub_strm, &p)) 696 { 697 // The stream had all it needed 698 s.Write(sub_strm.GetData(), sub_strm.GetSize()); 699 } 700 if (*p != '}') 701 { 702 success = false; 703 break; 704 } 705 } 706 else if (*p == '}') 707 { 708 // End of a enclosing scope 709 break; 710 } 711 else if (*p == '$') 712 { 713 // We have a prompt variable to print 714 ++p; 715 if (*p == '{') 716 { 717 ++p; 718 const char *var_name_begin = p; 719 const char *var_name_end = ::strchr (p, '}'); 720 721 if (var_name_end && var_name_begin < var_name_end) 722 { 723 // if we have already failed to parse, skip this variable 724 if (success) 725 { 726 const char *cstr = NULL; 727 Address format_addr; 728 bool calculate_format_addr_function_offset = false; 729 // Set reg_kind and reg_num to invalid values 730 RegisterKind reg_kind = kNumRegisterKinds; 731 uint32_t reg_num = LLDB_INVALID_REGNUM; 732 FileSpec format_file_spec; 733 const RegisterInfo *reg_info = NULL; 734 RegisterContext *reg_ctx = NULL; 735 736 // Each variable must set success to true below... 737 bool var_success = false; 738 switch (var_name_begin[0]) 739 { 740 case 'a': 741 if (::strncmp (var_name_begin, "addr}", strlen("addr}")) == 0) 742 { 743 if (addr && addr->IsValid()) 744 { 745 var_success = true; 746 format_addr = *addr; 747 } 748 } 749 break; 750 751 case 'p': 752 if (::strncmp (var_name_begin, "process.", strlen("process.")) == 0) 753 { 754 if (exe_ctx && exe_ctx->process != NULL) 755 { 756 var_name_begin += ::strlen ("process."); 757 if (::strncmp (var_name_begin, "id}", strlen("id}")) == 0) 758 { 759 s.Printf("%i", exe_ctx->process->GetID()); 760 var_success = true; 761 } 762 else if ((::strncmp (var_name_begin, "name}", strlen("name}")) == 0) || 763 (::strncmp (var_name_begin, "file.basename}", strlen("file.basename}")) == 0) || 764 (::strncmp (var_name_begin, "file.fullpath}", strlen("file.fullpath}")) == 0)) 765 { 766 ModuleSP exe_module_sp (exe_ctx->process->GetTarget().GetExecutableModule()); 767 if (exe_module_sp) 768 { 769 if (var_name_begin[0] == 'n' || var_name_begin[5] == 'f') 770 { 771 format_file_spec.GetFilename() = exe_module_sp->GetFileSpec().GetFilename(); 772 var_success = format_file_spec; 773 } 774 else 775 { 776 format_file_spec = exe_module_sp->GetFileSpec(); 777 var_success = format_file_spec; 778 } 779 } 780 } 781 } 782 } 783 break; 784 785 case 't': 786 if (::strncmp (var_name_begin, "thread.", strlen("thread.")) == 0) 787 { 788 if (exe_ctx && exe_ctx->thread) 789 { 790 var_name_begin += ::strlen ("thread."); 791 if (::strncmp (var_name_begin, "id}", strlen("id}")) == 0) 792 { 793 s.Printf("0x%4.4x", exe_ctx->thread->GetID()); 794 var_success = true; 795 } 796 else if (::strncmp (var_name_begin, "index}", strlen("index}")) == 0) 797 { 798 s.Printf("%u", exe_ctx->thread->GetIndexID()); 799 var_success = true; 800 } 801 else if (::strncmp (var_name_begin, "name}", strlen("name}")) == 0) 802 { 803 cstr = exe_ctx->thread->GetName(); 804 var_success = cstr && cstr[0]; 805 if (var_success) 806 s.PutCString(cstr); 807 } 808 else if (::strncmp (var_name_begin, "queue}", strlen("queue}")) == 0) 809 { 810 cstr = exe_ctx->thread->GetQueueName(); 811 var_success = cstr && cstr[0]; 812 if (var_success) 813 s.PutCString(cstr); 814 } 815 else if (::strncmp (var_name_begin, "stop-reason}", strlen("stop-reason}")) == 0) 816 { 817 StopInfoSP stop_info_sp = exe_ctx->thread->GetStopInfo (); 818 if (stop_info_sp) 819 { 820 cstr = stop_info_sp->GetDescription(); 821 if (cstr && cstr[0]) 822 { 823 s.PutCString(cstr); 824 var_success = true; 825 } 826 } 827 } 828 } 829 } 830 else if (::strncmp (var_name_begin, "target.", strlen("target.")) == 0) 831 { 832 Target *target = Target::GetTargetFromContexts (exe_ctx, sc); 833 if (target) 834 { 835 var_name_begin += ::strlen ("target."); 836 if (::strncmp (var_name_begin, "arch}", strlen("arch}")) == 0) 837 { 838 ArchSpec arch (target->GetArchitecture ()); 839 if (arch.IsValid()) 840 { 841 s.PutCString (arch.GetArchitectureName()); 842 var_success = true; 843 } 844 } 845 } 846 } 847 break; 848 849 850 case 'm': 851 if (::strncmp (var_name_begin, "module.", strlen("module.")) == 0) 852 { 853 if (sc && sc->module_sp.get()) 854 { 855 Module *module = sc->module_sp.get(); 856 var_name_begin += ::strlen ("module."); 857 858 if (::strncmp (var_name_begin, "file.", strlen("file.")) == 0) 859 { 860 if (module->GetFileSpec()) 861 { 862 var_name_begin += ::strlen ("file."); 863 864 if (::strncmp (var_name_begin, "basename}", strlen("basename}")) == 0) 865 { 866 format_file_spec.GetFilename() = module->GetFileSpec().GetFilename(); 867 var_success = format_file_spec; 868 } 869 else if (::strncmp (var_name_begin, "fullpath}", strlen("fullpath}")) == 0) 870 { 871 format_file_spec = module->GetFileSpec(); 872 var_success = format_file_spec; 873 } 874 } 875 } 876 } 877 } 878 break; 879 880 881 case 'f': 882 if (::strncmp (var_name_begin, "file.", strlen("file.")) == 0) 883 { 884 if (sc && sc->comp_unit != NULL) 885 { 886 var_name_begin += ::strlen ("file."); 887 888 if (::strncmp (var_name_begin, "basename}", strlen("basename}")) == 0) 889 { 890 format_file_spec.GetFilename() = sc->comp_unit->GetFilename(); 891 var_success = format_file_spec; 892 } 893 else if (::strncmp (var_name_begin, "fullpath}", strlen("fullpath}")) == 0) 894 { 895 format_file_spec = *sc->comp_unit; 896 var_success = format_file_spec; 897 } 898 } 899 } 900 else if (::strncmp (var_name_begin, "frame.", strlen("frame.")) == 0) 901 { 902 if (exe_ctx && exe_ctx->frame) 903 { 904 var_name_begin += ::strlen ("frame."); 905 if (::strncmp (var_name_begin, "index}", strlen("index}")) == 0) 906 { 907 s.Printf("%u", exe_ctx->frame->GetFrameIndex()); 908 var_success = true; 909 } 910 else if (::strncmp (var_name_begin, "pc}", strlen("pc}")) == 0) 911 { 912 reg_kind = eRegisterKindGeneric; 913 reg_num = LLDB_REGNUM_GENERIC_PC; 914 var_success = true; 915 } 916 else if (::strncmp (var_name_begin, "sp}", strlen("sp}")) == 0) 917 { 918 reg_kind = eRegisterKindGeneric; 919 reg_num = LLDB_REGNUM_GENERIC_SP; 920 var_success = true; 921 } 922 else if (::strncmp (var_name_begin, "fp}", strlen("fp}")) == 0) 923 { 924 reg_kind = eRegisterKindGeneric; 925 reg_num = LLDB_REGNUM_GENERIC_FP; 926 var_success = true; 927 } 928 else if (::strncmp (var_name_begin, "flags}", strlen("flags}")) == 0) 929 { 930 reg_kind = eRegisterKindGeneric; 931 reg_num = LLDB_REGNUM_GENERIC_FLAGS; 932 var_success = true; 933 } 934 else if (::strncmp (var_name_begin, "reg.", strlen ("reg.")) == 0) 935 { 936 reg_ctx = exe_ctx->frame->GetRegisterContext().get(); 937 if (reg_ctx) 938 { 939 var_name_begin += ::strlen ("reg."); 940 if (var_name_begin < var_name_end) 941 { 942 std::string reg_name (var_name_begin, var_name_end); 943 reg_info = reg_ctx->GetRegisterInfoByName (reg_name.c_str()); 944 if (reg_info) 945 var_success = true; 946 } 947 } 948 } 949 } 950 } 951 else if (::strncmp (var_name_begin, "function.", strlen("function.")) == 0) 952 { 953 if (sc && (sc->function != NULL || sc->symbol != NULL)) 954 { 955 var_name_begin += ::strlen ("function."); 956 if (::strncmp (var_name_begin, "id}", strlen("id}")) == 0) 957 { 958 if (sc->function) 959 s.Printf("function{0x%8.8x}", sc->function->GetID()); 960 else 961 s.Printf("symbol[%u]", sc->symbol->GetID()); 962 963 var_success = true; 964 } 965 else if (::strncmp (var_name_begin, "name}", strlen("name}")) == 0) 966 { 967 if (sc->function) 968 cstr = sc->function->GetName().AsCString (NULL); 969 else if (sc->symbol) 970 cstr = sc->symbol->GetName().AsCString (NULL); 971 if (cstr) 972 { 973 s.PutCString(cstr); 974 975 if (sc->block) 976 { 977 Block *inline_block = sc->block->GetContainingInlinedBlock (); 978 if (inline_block) 979 { 980 const InlineFunctionInfo *inline_info = sc->block->GetInlinedFunctionInfo(); 981 if (inline_info) 982 { 983 s.PutCString(" [inlined] "); 984 inline_info->GetName().Dump(&s); 985 } 986 } 987 } 988 var_success = true; 989 } 990 } 991 else if (::strncmp (var_name_begin, "addr-offset}", strlen("addr-offset}")) == 0) 992 { 993 var_success = addr != NULL; 994 if (var_success) 995 { 996 format_addr = *addr; 997 calculate_format_addr_function_offset = true; 998 } 999 } 1000 else if (::strncmp (var_name_begin, "line-offset}", strlen("line-offset}")) == 0) 1001 { 1002 var_success = sc->line_entry.range.GetBaseAddress().IsValid(); 1003 if (var_success) 1004 { 1005 format_addr = sc->line_entry.range.GetBaseAddress(); 1006 calculate_format_addr_function_offset = true; 1007 } 1008 } 1009 else if (::strncmp (var_name_begin, "pc-offset}", strlen("pc-offset}")) == 0) 1010 { 1011 var_success = exe_ctx->frame; 1012 if (var_success) 1013 { 1014 format_addr = exe_ctx->frame->GetFrameCodeAddress(); 1015 calculate_format_addr_function_offset = true; 1016 } 1017 } 1018 } 1019 } 1020 break; 1021 1022 case 'l': 1023 if (::strncmp (var_name_begin, "line.", strlen("line.")) == 0) 1024 { 1025 if (sc && sc->line_entry.IsValid()) 1026 { 1027 var_name_begin += ::strlen ("line."); 1028 if (::strncmp (var_name_begin, "file.", strlen("file.")) == 0) 1029 { 1030 var_name_begin += ::strlen ("file."); 1031 1032 if (::strncmp (var_name_begin, "basename}", strlen("basename}")) == 0) 1033 { 1034 format_file_spec.GetFilename() = sc->line_entry.file.GetFilename(); 1035 var_success = format_file_spec; 1036 } 1037 else if (::strncmp (var_name_begin, "fullpath}", strlen("fullpath}")) == 0) 1038 { 1039 format_file_spec = sc->line_entry.file; 1040 var_success = format_file_spec; 1041 } 1042 } 1043 else if (::strncmp (var_name_begin, "number}", strlen("number}")) == 0) 1044 { 1045 var_success = true; 1046 s.Printf("%u", sc->line_entry.line); 1047 } 1048 else if ((::strncmp (var_name_begin, "start-addr}", strlen("start-addr}")) == 0) || 1049 (::strncmp (var_name_begin, "end-addr}", strlen("end-addr}")) == 0)) 1050 { 1051 var_success = sc && sc->line_entry.range.GetBaseAddress().IsValid(); 1052 if (var_success) 1053 { 1054 format_addr = sc->line_entry.range.GetBaseAddress(); 1055 if (var_name_begin[0] == 'e') 1056 format_addr.Slide (sc->line_entry.range.GetByteSize()); 1057 } 1058 } 1059 } 1060 } 1061 break; 1062 } 1063 1064 if (var_success) 1065 { 1066 // If format addr is valid, then we need to print an address 1067 if (reg_num != LLDB_INVALID_REGNUM) 1068 { 1069 // We have a register value to display... 1070 if (reg_num == LLDB_REGNUM_GENERIC_PC && reg_kind == eRegisterKindGeneric) 1071 { 1072 format_addr = exe_ctx->frame->GetFrameCodeAddress(); 1073 } 1074 else 1075 { 1076 if (reg_ctx == NULL) 1077 reg_ctx = exe_ctx->frame->GetRegisterContext().get(); 1078 1079 if (reg_ctx) 1080 { 1081 if (reg_kind != kNumRegisterKinds) 1082 reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(reg_kind, reg_num); 1083 reg_info = reg_ctx->GetRegisterInfoAtIndex (reg_num); 1084 var_success = reg_info != NULL; 1085 } 1086 } 1087 } 1088 1089 if (reg_info != NULL) 1090 { 1091 DataExtractor reg_data; 1092 var_success = reg_ctx->ReadRegisterBytes (reg_info->kinds[eRegisterKindLLDB], reg_data); 1093 { 1094 reg_data.Dump(&s, 0, reg_info->format, reg_info->byte_size, 1, UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0); 1095 } 1096 } 1097 1098 if (format_file_spec) 1099 { 1100 s << format_file_spec; 1101 } 1102 1103 // If format addr is valid, then we need to print an address 1104 if (format_addr.IsValid()) 1105 { 1106 var_success = false; 1107 1108 if (calculate_format_addr_function_offset) 1109 { 1110 Address func_addr; 1111 1112 if (sc) 1113 { 1114 if (sc->function) 1115 { 1116 func_addr = sc->function->GetAddressRange().GetBaseAddress(); 1117 if (sc->block) 1118 { 1119 // Check to make sure we aren't in an inline 1120 // function. If we are, use the inline block 1121 // range that contains "format_addr" since 1122 // blocks can be discontiguous. 1123 Block *inline_block = sc->block->GetContainingInlinedBlock (); 1124 AddressRange inline_range; 1125 if (inline_block && inline_block->GetRangeContainingAddress (format_addr, inline_range)) 1126 func_addr = inline_range.GetBaseAddress(); 1127 } 1128 } 1129 else if (sc->symbol && sc->symbol->GetAddressRangePtr()) 1130 func_addr = sc->symbol->GetAddressRangePtr()->GetBaseAddress(); 1131 } 1132 1133 if (func_addr.IsValid()) 1134 { 1135 if (func_addr.GetSection() == format_addr.GetSection()) 1136 { 1137 addr_t func_file_addr = func_addr.GetFileAddress(); 1138 addr_t addr_file_addr = format_addr.GetFileAddress(); 1139 if (addr_file_addr > func_file_addr) 1140 s.Printf(" + %llu", addr_file_addr - func_file_addr); 1141 else if (addr_file_addr < func_file_addr) 1142 s.Printf(" - %llu", func_file_addr - addr_file_addr); 1143 var_success = true; 1144 } 1145 else 1146 { 1147 Target *target = Target::GetTargetFromContexts (exe_ctx, sc); 1148 if (target) 1149 { 1150 addr_t func_load_addr = func_addr.GetLoadAddress (target); 1151 addr_t addr_load_addr = format_addr.GetLoadAddress (target); 1152 if (addr_load_addr > func_load_addr) 1153 s.Printf(" + %llu", addr_load_addr - func_load_addr); 1154 else if (addr_load_addr < func_load_addr) 1155 s.Printf(" - %llu", func_load_addr - addr_load_addr); 1156 var_success = true; 1157 } 1158 } 1159 } 1160 } 1161 else 1162 { 1163 Target *target = Target::GetTargetFromContexts (exe_ctx, sc); 1164 addr_t vaddr = LLDB_INVALID_ADDRESS; 1165 if (exe_ctx && !target->GetSectionLoadList().IsEmpty()) 1166 vaddr = format_addr.GetLoadAddress (target); 1167 if (vaddr == LLDB_INVALID_ADDRESS) 1168 vaddr = format_addr.GetFileAddress (); 1169 1170 if (vaddr != LLDB_INVALID_ADDRESS) 1171 { 1172 int addr_width = target->GetArchitecture().GetAddressByteSize() * 2; 1173 if (addr_width == 0) 1174 addr_width = 16; 1175 s.Printf("0x%*.*llx", addr_width, addr_width, vaddr); 1176 var_success = true; 1177 } 1178 } 1179 } 1180 } 1181 1182 if (var_success == false) 1183 success = false; 1184 } 1185 p = var_name_end; 1186 } 1187 else 1188 break; 1189 } 1190 else 1191 { 1192 // We got a dollar sign with no '{' after it, it must just be a dollar sign 1193 s.PutChar(*p); 1194 } 1195 } 1196 else if (*p == '\\') 1197 { 1198 ++p; // skip the slash 1199 switch (*p) 1200 { 1201 case 'a': s.PutChar ('\a'); break; 1202 case 'b': s.PutChar ('\b'); break; 1203 case 'f': s.PutChar ('\f'); break; 1204 case 'n': s.PutChar ('\n'); break; 1205 case 'r': s.PutChar ('\r'); break; 1206 case 't': s.PutChar ('\t'); break; 1207 case 'v': s.PutChar ('\v'); break; 1208 case '\'': s.PutChar ('\''); break; 1209 case '\\': s.PutChar ('\\'); break; 1210 case '0': 1211 // 1 to 3 octal chars 1212 { 1213 // Make a string that can hold onto the initial zero char, 1214 // up to 3 octal digits, and a terminating NULL. 1215 char oct_str[5] = { 0, 0, 0, 0, 0 }; 1216 1217 int i; 1218 for (i=0; (p[i] >= '0' && p[i] <= '7') && i<4; ++i) 1219 oct_str[i] = p[i]; 1220 1221 // We don't want to consume the last octal character since 1222 // the main for loop will do this for us, so we advance p by 1223 // one less than i (even if i is zero) 1224 p += i - 1; 1225 unsigned long octal_value = ::strtoul (oct_str, NULL, 8); 1226 if (octal_value <= UINT8_MAX) 1227 { 1228 char octal_char = octal_value; 1229 s.Write (&octal_char, 1); 1230 } 1231 } 1232 break; 1233 1234 case 'x': 1235 // hex number in the format 1236 if (isxdigit(p[1])) 1237 { 1238 ++p; // Skip the 'x' 1239 1240 // Make a string that can hold onto two hex chars plus a 1241 // NULL terminator 1242 char hex_str[3] = { 0,0,0 }; 1243 hex_str[0] = *p; 1244 if (isxdigit(p[1])) 1245 { 1246 ++p; // Skip the first of the two hex chars 1247 hex_str[1] = *p; 1248 } 1249 1250 unsigned long hex_value = strtoul (hex_str, NULL, 16); 1251 if (hex_value <= UINT8_MAX) 1252 s.PutChar (hex_value); 1253 } 1254 else 1255 { 1256 s.PutChar('x'); 1257 } 1258 break; 1259 1260 default: 1261 // Just desensitize any other character by just printing what 1262 // came after the '\' 1263 s << *p; 1264 break; 1265 1266 } 1267 1268 } 1269 } 1270 if (end) 1271 *end = p; 1272 return success; 1273 } 1274 1275 #pragma mark Debugger::SettingsController 1276 1277 //-------------------------------------------------- 1278 // class Debugger::SettingsController 1279 //-------------------------------------------------- 1280 1281 Debugger::SettingsController::SettingsController () : 1282 UserSettingsController ("", lldb::UserSettingsControllerSP()) 1283 { 1284 m_default_settings.reset (new DebuggerInstanceSettings (*this, false, 1285 InstanceSettings::GetDefaultName().AsCString())); 1286 } 1287 1288 Debugger::SettingsController::~SettingsController () 1289 { 1290 } 1291 1292 1293 lldb::InstanceSettingsSP 1294 Debugger::SettingsController::CreateInstanceSettings (const char *instance_name) 1295 { 1296 DebuggerInstanceSettings *new_settings = new DebuggerInstanceSettings (*GetSettingsController(), 1297 false, instance_name); 1298 lldb::InstanceSettingsSP new_settings_sp (new_settings); 1299 return new_settings_sp; 1300 } 1301 1302 #pragma mark DebuggerInstanceSettings 1303 //-------------------------------------------------- 1304 // class DebuggerInstanceSettings 1305 //-------------------------------------------------- 1306 1307 DebuggerInstanceSettings::DebuggerInstanceSettings 1308 ( 1309 UserSettingsController &owner, 1310 bool live_instance, 1311 const char *name 1312 ) : 1313 InstanceSettings (owner, name ? name : InstanceSettings::InvalidName().AsCString(), live_instance), 1314 m_term_width (80), 1315 m_prompt (), 1316 m_frame_format (), 1317 m_thread_format (), 1318 m_script_lang (), 1319 m_use_external_editor (false), 1320 m_auto_confirm_on (false) 1321 { 1322 // CopyInstanceSettings is a pure virtual function in InstanceSettings; it therefore cannot be called 1323 // until the vtables for DebuggerInstanceSettings are properly set up, i.e. AFTER all the initializers. 1324 // For this reason it has to be called here, rather than in the initializer or in the parent constructor. 1325 // The same is true of CreateInstanceName(). 1326 1327 if (GetInstanceName() == InstanceSettings::InvalidName()) 1328 { 1329 ChangeInstanceName (std::string (CreateInstanceName().AsCString())); 1330 m_owner.RegisterInstanceSettings (this); 1331 } 1332 1333 if (live_instance) 1334 { 1335 const lldb::InstanceSettingsSP &pending_settings = m_owner.FindPendingSettings (m_instance_name); 1336 CopyInstanceSettings (pending_settings, false); 1337 } 1338 } 1339 1340 DebuggerInstanceSettings::DebuggerInstanceSettings (const DebuggerInstanceSettings &rhs) : 1341 InstanceSettings (*Debugger::GetSettingsController(), CreateInstanceName ().AsCString()), 1342 m_prompt (rhs.m_prompt), 1343 m_frame_format (rhs.m_frame_format), 1344 m_thread_format (rhs.m_thread_format), 1345 m_script_lang (rhs.m_script_lang), 1346 m_use_external_editor (rhs.m_use_external_editor), 1347 m_auto_confirm_on(rhs.m_auto_confirm_on) 1348 { 1349 const lldb::InstanceSettingsSP &pending_settings = m_owner.FindPendingSettings (m_instance_name); 1350 CopyInstanceSettings (pending_settings, false); 1351 m_owner.RemovePendingSettings (m_instance_name); 1352 } 1353 1354 DebuggerInstanceSettings::~DebuggerInstanceSettings () 1355 { 1356 } 1357 1358 DebuggerInstanceSettings& 1359 DebuggerInstanceSettings::operator= (const DebuggerInstanceSettings &rhs) 1360 { 1361 if (this != &rhs) 1362 { 1363 m_term_width = rhs.m_term_width; 1364 m_prompt = rhs.m_prompt; 1365 m_frame_format = rhs.m_frame_format; 1366 m_thread_format = rhs.m_thread_format; 1367 m_script_lang = rhs.m_script_lang; 1368 m_use_external_editor = rhs.m_use_external_editor; 1369 m_auto_confirm_on = rhs.m_auto_confirm_on; 1370 } 1371 1372 return *this; 1373 } 1374 1375 bool 1376 DebuggerInstanceSettings::ValidTermWidthValue (const char *value, Error err) 1377 { 1378 bool valid = false; 1379 1380 // Verify we have a value string. 1381 if (value == NULL || value[0] == '\0') 1382 { 1383 err.SetErrorString ("Missing value. Can't set terminal width without a value.\n"); 1384 } 1385 else 1386 { 1387 char *end = NULL; 1388 const uint32_t width = ::strtoul (value, &end, 0); 1389 1390 if (end && end[0] == '\0') 1391 { 1392 if (width >= 10 && width <= 1024) 1393 valid = true; 1394 else 1395 err.SetErrorString ("Invalid term-width value; value must be between 10 and 1024.\n"); 1396 } 1397 else 1398 err.SetErrorStringWithFormat ("'%s' is not a valid unsigned integer string.\n", value); 1399 } 1400 1401 return valid; 1402 } 1403 1404 1405 void 1406 DebuggerInstanceSettings::UpdateInstanceSettingsVariable (const ConstString &var_name, 1407 const char *index_value, 1408 const char *value, 1409 const ConstString &instance_name, 1410 const SettingEntry &entry, 1411 VarSetOperationType op, 1412 Error &err, 1413 bool pending) 1414 { 1415 1416 if (var_name == TermWidthVarName()) 1417 { 1418 if (ValidTermWidthValue (value, err)) 1419 { 1420 m_term_width = ::strtoul (value, NULL, 0); 1421 } 1422 } 1423 else if (var_name == PromptVarName()) 1424 { 1425 UserSettingsController::UpdateStringVariable (op, m_prompt, value, err); 1426 if (!pending) 1427 { 1428 // 'instance_name' is actually (probably) in the form '[<instance_name>]'; if so, we need to 1429 // strip off the brackets before passing it to BroadcastPromptChange. 1430 1431 std::string tmp_instance_name (instance_name.AsCString()); 1432 if ((tmp_instance_name[0] == '[') 1433 && (tmp_instance_name[instance_name.GetLength() - 1] == ']')) 1434 tmp_instance_name = tmp_instance_name.substr (1, instance_name.GetLength() - 2); 1435 ConstString new_name (tmp_instance_name.c_str()); 1436 1437 BroadcastPromptChange (new_name, m_prompt.c_str()); 1438 } 1439 } 1440 else if (var_name == GetFrameFormatName()) 1441 { 1442 UserSettingsController::UpdateStringVariable (op, m_frame_format, value, err); 1443 } 1444 else if (var_name == GetThreadFormatName()) 1445 { 1446 UserSettingsController::UpdateStringVariable (op, m_thread_format, value, err); 1447 } 1448 else if (var_name == ScriptLangVarName()) 1449 { 1450 bool success; 1451 m_script_lang = Args::StringToScriptLanguage (value, eScriptLanguageDefault, 1452 &success); 1453 } 1454 else if (var_name == UseExternalEditorVarName ()) 1455 { 1456 UserSettingsController::UpdateBooleanVariable (op, m_use_external_editor, value, false, err); 1457 } 1458 else if (var_name == AutoConfirmName ()) 1459 { 1460 UserSettingsController::UpdateBooleanVariable (op, m_auto_confirm_on, value, false, err); 1461 } 1462 } 1463 1464 bool 1465 DebuggerInstanceSettings::GetInstanceSettingsValue (const SettingEntry &entry, 1466 const ConstString &var_name, 1467 StringList &value, 1468 Error *err) 1469 { 1470 if (var_name == PromptVarName()) 1471 { 1472 value.AppendString (m_prompt.c_str(), m_prompt.size()); 1473 1474 } 1475 else if (var_name == ScriptLangVarName()) 1476 { 1477 value.AppendString (ScriptInterpreter::LanguageToString (m_script_lang).c_str()); 1478 } 1479 else if (var_name == TermWidthVarName()) 1480 { 1481 StreamString width_str; 1482 width_str.Printf ("%d", m_term_width); 1483 value.AppendString (width_str.GetData()); 1484 } 1485 else if (var_name == GetFrameFormatName ()) 1486 { 1487 value.AppendString(m_frame_format.c_str(), m_frame_format.size()); 1488 } 1489 else if (var_name == GetThreadFormatName ()) 1490 { 1491 value.AppendString(m_thread_format.c_str(), m_thread_format.size()); 1492 } 1493 else if (var_name == UseExternalEditorVarName()) 1494 { 1495 if (m_use_external_editor) 1496 value.AppendString ("true"); 1497 else 1498 value.AppendString ("false"); 1499 } 1500 else if (var_name == AutoConfirmName()) 1501 { 1502 if (m_auto_confirm_on) 1503 value.AppendString ("true"); 1504 else 1505 value.AppendString ("false"); 1506 } 1507 else 1508 { 1509 if (err) 1510 err->SetErrorStringWithFormat ("unrecognized variable name '%s'", var_name.AsCString()); 1511 return false; 1512 } 1513 return true; 1514 } 1515 1516 void 1517 DebuggerInstanceSettings::CopyInstanceSettings (const lldb::InstanceSettingsSP &new_settings, 1518 bool pending) 1519 { 1520 if (new_settings.get() == NULL) 1521 return; 1522 1523 DebuggerInstanceSettings *new_debugger_settings = (DebuggerInstanceSettings *) new_settings.get(); 1524 1525 m_prompt = new_debugger_settings->m_prompt; 1526 if (!pending) 1527 { 1528 // 'instance_name' is actually (probably) in the form '[<instance_name>]'; if so, we need to 1529 // strip off the brackets before passing it to BroadcastPromptChange. 1530 1531 std::string tmp_instance_name (m_instance_name.AsCString()); 1532 if ((tmp_instance_name[0] == '[') 1533 && (tmp_instance_name[m_instance_name.GetLength() - 1] == ']')) 1534 tmp_instance_name = tmp_instance_name.substr (1, m_instance_name.GetLength() - 2); 1535 ConstString new_name (tmp_instance_name.c_str()); 1536 1537 BroadcastPromptChange (new_name, m_prompt.c_str()); 1538 } 1539 m_frame_format = new_debugger_settings->m_frame_format; 1540 m_thread_format = new_debugger_settings->m_thread_format; 1541 m_term_width = new_debugger_settings->m_term_width; 1542 m_script_lang = new_debugger_settings->m_script_lang; 1543 m_use_external_editor = new_debugger_settings->m_use_external_editor; 1544 m_auto_confirm_on = new_debugger_settings->m_auto_confirm_on; 1545 } 1546 1547 1548 bool 1549 DebuggerInstanceSettings::BroadcastPromptChange (const ConstString &instance_name, const char *new_prompt) 1550 { 1551 std::string tmp_prompt; 1552 1553 if (new_prompt != NULL) 1554 { 1555 tmp_prompt = new_prompt ; 1556 int len = tmp_prompt.size(); 1557 if (len > 1 1558 && (tmp_prompt[0] == '\'' || tmp_prompt[0] == '"') 1559 && (tmp_prompt[len-1] == tmp_prompt[0])) 1560 { 1561 tmp_prompt = tmp_prompt.substr(1,len-2); 1562 } 1563 len = tmp_prompt.size(); 1564 if (tmp_prompt[len-1] != ' ') 1565 tmp_prompt.append(" "); 1566 } 1567 EventSP new_event_sp; 1568 new_event_sp.reset (new Event(CommandInterpreter::eBroadcastBitResetPrompt, 1569 new EventDataBytes (tmp_prompt.c_str()))); 1570 1571 if (instance_name.GetLength() != 0) 1572 { 1573 // Set prompt for a particular instance. 1574 Debugger *dbg = Debugger::FindDebuggerWithInstanceName (instance_name).get(); 1575 if (dbg != NULL) 1576 { 1577 dbg->GetCommandInterpreter().BroadcastEvent (new_event_sp); 1578 } 1579 } 1580 1581 return true; 1582 } 1583 1584 const ConstString 1585 DebuggerInstanceSettings::CreateInstanceName () 1586 { 1587 static int instance_count = 1; 1588 StreamString sstr; 1589 1590 sstr.Printf ("debugger_%d", instance_count); 1591 ++instance_count; 1592 1593 const ConstString ret_val (sstr.GetData()); 1594 1595 return ret_val; 1596 } 1597 1598 const ConstString & 1599 DebuggerInstanceSettings::PromptVarName () 1600 { 1601 static ConstString prompt_var_name ("prompt"); 1602 1603 return prompt_var_name; 1604 } 1605 1606 const ConstString & 1607 DebuggerInstanceSettings::GetFrameFormatName () 1608 { 1609 static ConstString prompt_var_name ("frame-format"); 1610 1611 return prompt_var_name; 1612 } 1613 1614 const ConstString & 1615 DebuggerInstanceSettings::GetThreadFormatName () 1616 { 1617 static ConstString prompt_var_name ("thread-format"); 1618 1619 return prompt_var_name; 1620 } 1621 1622 const ConstString & 1623 DebuggerInstanceSettings::ScriptLangVarName () 1624 { 1625 static ConstString script_lang_var_name ("script-lang"); 1626 1627 return script_lang_var_name; 1628 } 1629 1630 const ConstString & 1631 DebuggerInstanceSettings::TermWidthVarName () 1632 { 1633 static ConstString term_width_var_name ("term-width"); 1634 1635 return term_width_var_name; 1636 } 1637 1638 const ConstString & 1639 DebuggerInstanceSettings::UseExternalEditorVarName () 1640 { 1641 static ConstString use_external_editor_var_name ("use-external-editor"); 1642 1643 return use_external_editor_var_name; 1644 } 1645 1646 const ConstString & 1647 DebuggerInstanceSettings::AutoConfirmName () 1648 { 1649 static ConstString use_external_editor_var_name ("auto-confirm"); 1650 1651 return use_external_editor_var_name; 1652 } 1653 1654 //-------------------------------------------------- 1655 // SettingsController Variable Tables 1656 //-------------------------------------------------- 1657 1658 1659 SettingEntry 1660 Debugger::SettingsController::global_settings_table[] = 1661 { 1662 //{ "var-name", var-type, "default", enum-table, init'd, hidden, "help-text"}, 1663 // The Debugger level global table should always be empty; all Debugger settable variables should be instance 1664 // variables. 1665 { NULL, eSetVarTypeNone, NULL, NULL, 0, 0, NULL } 1666 }; 1667 1668 #define MODULE_WITH_FUNC "{ ${module.file.basename}{`${function.name}${function.pc-offset}}}" 1669 #define FILE_AND_LINE "{ at ${line.file.basename}:${line.number}}" 1670 1671 #define DEFAULT_THREAD_FORMAT "thread #${thread.index}: tid = ${thread.id}"\ 1672 "{, ${frame.pc}}"\ 1673 MODULE_WITH_FUNC\ 1674 FILE_AND_LINE\ 1675 "{, stop reason = ${thread.stop-reason}}"\ 1676 "\\n" 1677 1678 //#define DEFAULT_THREAD_FORMAT "thread #${thread.index}: tid = ${thread.id}"\ 1679 // "{, ${frame.pc}}"\ 1680 // MODULE_WITH_FUNC\ 1681 // FILE_AND_LINE\ 1682 // "{, stop reason = ${thread.stop-reason}}"\ 1683 // "{, name = ${thread.name}}"\ 1684 // "{, queue = ${thread.queue}}"\ 1685 // "\\n" 1686 1687 #define DEFAULT_FRAME_FORMAT "frame #${frame.index}: ${frame.pc}"\ 1688 MODULE_WITH_FUNC\ 1689 FILE_AND_LINE\ 1690 "\\n" 1691 1692 SettingEntry 1693 Debugger::SettingsController::instance_settings_table[] = 1694 { 1695 // NAME Setting variable type Default Enum Init'd Hidden Help 1696 // ======================= ======================= ====================== ==== ====== ====== ====================== 1697 { "frame-format", eSetVarTypeString, DEFAULT_FRAME_FORMAT, NULL, false, false, "The default frame format string to use when displaying thread information." }, 1698 { "prompt", eSetVarTypeString, "(lldb) ", NULL, false, false, "The debugger command line prompt displayed for the user." }, 1699 { "script-lang", eSetVarTypeString, "python", NULL, false, false, "The script language to be used for evaluating user-written scripts." }, 1700 { "term-width", eSetVarTypeInt, "80" , NULL, false, false, "The maximum number of columns to use for displaying text." }, 1701 { "thread-format", eSetVarTypeString, DEFAULT_THREAD_FORMAT, NULL, false, false, "The default thread format string to use when displaying thread information." }, 1702 { "use-external-editor", eSetVarTypeBoolean, "false", NULL, false, false, "Whether to use an external editor or not." }, 1703 { "auto-confirm", eSetVarTypeBoolean, "false", NULL, false, false, "If true all confirmation prompts will receive their default reply." }, 1704 { NULL, eSetVarTypeNone, NULL, NULL, false, false, NULL } 1705 }; 1706