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::WriteToDefaultReader (const char *bytes, size_t bytes_len) 427 { 428 if (bytes && bytes_len) 429 m_input_reader_data.append (bytes, bytes_len); 430 431 if (m_input_reader_data.empty()) 432 return; 433 434 while (!m_input_readers.empty() && !m_input_reader_data.empty()) 435 { 436 // Get the input reader from the top of the stack 437 InputReaderSP reader_sp (GetCurrentInputReader ()); 438 if (!reader_sp) 439 break; 440 441 size_t bytes_handled = reader_sp->HandleRawBytes (m_input_reader_data.c_str(), 442 m_input_reader_data.size()); 443 if (bytes_handled) 444 { 445 m_input_reader_data.erase (0, bytes_handled); 446 } 447 else 448 { 449 // No bytes were handled, we might not have reached our 450 // granularity, just return and wait for more data 451 break; 452 } 453 } 454 455 // Flush out any input readers that are done. 456 while (CheckIfTopInputReaderIsDone ()) 457 /* Do nothing. */; 458 459 } 460 461 void 462 Debugger::PushInputReader (const InputReaderSP& reader_sp) 463 { 464 if (!reader_sp) 465 return; 466 467 // Deactivate the old top reader 468 InputReaderSP top_reader_sp (GetCurrentInputReader ()); 469 470 if (top_reader_sp) 471 top_reader_sp->Notify (eInputReaderDeactivate); 472 473 m_input_readers.push (reader_sp); 474 reader_sp->Notify (eInputReaderActivate); 475 ActivateInputReader (reader_sp); 476 } 477 478 bool 479 Debugger::PopInputReader (const lldb::InputReaderSP& pop_reader_sp) 480 { 481 bool result = false; 482 483 // The reader on the stop of the stack is done, so let the next 484 // read on the stack referesh its prompt and if there is one... 485 if (!m_input_readers.empty()) 486 { 487 // Cannot call GetCurrentInputReader here, as that would cause an infinite loop. 488 InputReaderSP reader_sp(m_input_readers.top()); 489 490 if (!pop_reader_sp || pop_reader_sp.get() == reader_sp.get()) 491 { 492 m_input_readers.pop (); 493 reader_sp->Notify (eInputReaderDeactivate); 494 reader_sp->Notify (eInputReaderDone); 495 result = true; 496 497 if (!m_input_readers.empty()) 498 { 499 reader_sp = m_input_readers.top(); 500 if (reader_sp) 501 { 502 ActivateInputReader (reader_sp); 503 reader_sp->Notify (eInputReaderReactivate); 504 } 505 } 506 } 507 } 508 return result; 509 } 510 511 bool 512 Debugger::CheckIfTopInputReaderIsDone () 513 { 514 bool result = false; 515 if (!m_input_readers.empty()) 516 { 517 // Cannot call GetCurrentInputReader here, as that would cause an infinite loop. 518 InputReaderSP reader_sp(m_input_readers.top()); 519 520 if (reader_sp && reader_sp->IsDone()) 521 { 522 result = true; 523 PopInputReader (reader_sp); 524 } 525 } 526 return result; 527 } 528 529 void 530 Debugger::ActivateInputReader (const InputReaderSP &reader_sp) 531 { 532 int input_fd = m_input_file.GetFile().GetDescriptor(); 533 534 if (input_fd >= 0) 535 { 536 Terminal tty(input_fd); 537 538 tty.SetEcho(reader_sp->GetEcho()); 539 540 switch (reader_sp->GetGranularity()) 541 { 542 case eInputReaderGranularityByte: 543 case eInputReaderGranularityWord: 544 tty.SetCanonical (false); 545 break; 546 547 case eInputReaderGranularityLine: 548 case eInputReaderGranularityAll: 549 tty.SetCanonical (true); 550 break; 551 552 default: 553 break; 554 } 555 } 556 } 557 558 DebuggerSP 559 Debugger::FindDebuggerWithID (lldb::user_id_t id) 560 { 561 lldb::DebuggerSP debugger_sp; 562 563 Mutex::Locker locker (GetDebuggerListMutex ()); 564 DebuggerList &debugger_list = GetDebuggerList(); 565 DebuggerList::iterator pos, end = debugger_list.end(); 566 for (pos = debugger_list.begin(); pos != end; ++pos) 567 { 568 if ((*pos).get()->GetID() == id) 569 { 570 debugger_sp = *pos; 571 break; 572 } 573 } 574 return debugger_sp; 575 } 576 577 static void 578 TestPromptFormats (StackFrame *frame) 579 { 580 if (frame == NULL) 581 return; 582 583 StreamString s; 584 const char *prompt_format = 585 "{addr = '${addr}'\n}" 586 "{process.id = '${process.id}'\n}" 587 "{process.name = '${process.name}'\n}" 588 "{process.file.basename = '${process.file.basename}'\n}" 589 "{process.file.fullpath = '${process.file.fullpath}'\n}" 590 "{thread.id = '${thread.id}'\n}" 591 "{thread.index = '${thread.index}'\n}" 592 "{thread.name = '${thread.name}'\n}" 593 "{thread.queue = '${thread.queue}'\n}" 594 "{thread.stop-reason = '${thread.stop-reason}'\n}" 595 "{target.arch = '${target.arch}'\n}" 596 "{module.file.basename = '${module.file.basename}'\n}" 597 "{module.file.fullpath = '${module.file.fullpath}'\n}" 598 "{file.basename = '${file.basename}'\n}" 599 "{file.fullpath = '${file.fullpath}'\n}" 600 "{frame.index = '${frame.index}'\n}" 601 "{frame.pc = '${frame.pc}'\n}" 602 "{frame.sp = '${frame.sp}'\n}" 603 "{frame.fp = '${frame.fp}'\n}" 604 "{frame.flags = '${frame.flags}'\n}" 605 "{frame.reg.rdi = '${frame.reg.rdi}'\n}" 606 "{frame.reg.rip = '${frame.reg.rip}'\n}" 607 "{frame.reg.rsp = '${frame.reg.rsp}'\n}" 608 "{frame.reg.rbp = '${frame.reg.rbp}'\n}" 609 "{frame.reg.rflags = '${frame.reg.rflags}'\n}" 610 "{frame.reg.xmm0 = '${frame.reg.xmm0}'\n}" 611 "{frame.reg.carp = '${frame.reg.carp}'\n}" 612 "{function.id = '${function.id}'\n}" 613 "{function.name = '${function.name}'\n}" 614 "{function.addr-offset = '${function.addr-offset}'\n}" 615 "{function.line-offset = '${function.line-offset}'\n}" 616 "{function.pc-offset = '${function.pc-offset}'\n}" 617 "{line.file.basename = '${line.file.basename}'\n}" 618 "{line.file.fullpath = '${line.file.fullpath}'\n}" 619 "{line.number = '${line.number}'\n}" 620 "{line.start-addr = '${line.start-addr}'\n}" 621 "{line.end-addr = '${line.end-addr}'\n}" 622 ; 623 624 SymbolContext sc (frame->GetSymbolContext(eSymbolContextEverything)); 625 ExecutionContext exe_ctx; 626 frame->CalculateExecutionContext(exe_ctx); 627 const char *end = NULL; 628 if (Debugger::FormatPrompt (prompt_format, &sc, &exe_ctx, &sc.line_entry.range.GetBaseAddress(), s, &end)) 629 { 630 printf("%s\n", s.GetData()); 631 } 632 else 633 { 634 printf ("error: at '%s'\n", end); 635 printf ("what we got: %s\n", s.GetData()); 636 } 637 } 638 639 bool 640 Debugger::FormatPrompt 641 ( 642 const char *format, 643 const SymbolContext *sc, 644 const ExecutionContext *exe_ctx, 645 const Address *addr, 646 Stream &s, 647 const char **end 648 ) 649 { 650 bool success = true; 651 const char *p; 652 for (p = format; *p != '\0'; ++p) 653 { 654 size_t non_special_chars = ::strcspn (p, "${}\\"); 655 if (non_special_chars > 0) 656 { 657 if (success) 658 s.Write (p, non_special_chars); 659 p += non_special_chars; 660 } 661 662 if (*p == '\0') 663 { 664 break; 665 } 666 else if (*p == '{') 667 { 668 // Start a new scope that must have everything it needs if it is to 669 // to make it into the final output stream "s". If you want to make 670 // a format that only prints out the function or symbol name if there 671 // is one in the symbol context you can use: 672 // "{function =${function.name}}" 673 // The first '{' starts a new scope that end with the matching '}' at 674 // the end of the string. The contents "function =${function.name}" 675 // will then be evaluated and only be output if there is a function 676 // or symbol with a valid name. 677 StreamString sub_strm; 678 679 ++p; // Skip the '{' 680 681 if (FormatPrompt (p, sc, exe_ctx, addr, sub_strm, &p)) 682 { 683 // The stream had all it needed 684 s.Write(sub_strm.GetData(), sub_strm.GetSize()); 685 } 686 if (*p != '}') 687 { 688 success = false; 689 break; 690 } 691 } 692 else if (*p == '}') 693 { 694 // End of a enclosing scope 695 break; 696 } 697 else if (*p == '$') 698 { 699 // We have a prompt variable to print 700 ++p; 701 if (*p == '{') 702 { 703 ++p; 704 const char *var_name_begin = p; 705 const char *var_name_end = ::strchr (p, '}'); 706 707 if (var_name_end && var_name_begin < var_name_end) 708 { 709 // if we have already failed to parse, skip this variable 710 if (success) 711 { 712 const char *cstr = NULL; 713 Address format_addr; 714 bool calculate_format_addr_function_offset = false; 715 // Set reg_kind and reg_num to invalid values 716 RegisterKind reg_kind = kNumRegisterKinds; 717 uint32_t reg_num = LLDB_INVALID_REGNUM; 718 FileSpec format_file_spec; 719 const RegisterInfo *reg_info = NULL; 720 RegisterContext *reg_ctx = NULL; 721 722 // Each variable must set success to true below... 723 bool var_success = false; 724 switch (var_name_begin[0]) 725 { 726 case 'a': 727 if (::strncmp (var_name_begin, "addr}", strlen("addr}")) == 0) 728 { 729 if (addr && addr->IsValid()) 730 { 731 var_success = true; 732 format_addr = *addr; 733 } 734 } 735 break; 736 737 case 'p': 738 if (::strncmp (var_name_begin, "process.", strlen("process.")) == 0) 739 { 740 if (exe_ctx && exe_ctx->process != NULL) 741 { 742 var_name_begin += ::strlen ("process."); 743 if (::strncmp (var_name_begin, "id}", strlen("id}")) == 0) 744 { 745 s.Printf("%i", exe_ctx->process->GetID()); 746 var_success = true; 747 } 748 else if ((::strncmp (var_name_begin, "name}", strlen("name}")) == 0) || 749 (::strncmp (var_name_begin, "file.basename}", strlen("file.basename}")) == 0) || 750 (::strncmp (var_name_begin, "file.fullpath}", strlen("file.fullpath}")) == 0)) 751 { 752 ModuleSP exe_module_sp (exe_ctx->process->GetTarget().GetExecutableModule()); 753 if (exe_module_sp) 754 { 755 if (var_name_begin[0] == 'n' || var_name_begin[5] == 'f') 756 { 757 format_file_spec.GetFilename() = exe_module_sp->GetFileSpec().GetFilename(); 758 var_success = format_file_spec; 759 } 760 else 761 { 762 format_file_spec = exe_module_sp->GetFileSpec(); 763 var_success = format_file_spec; 764 } 765 } 766 } 767 } 768 } 769 break; 770 771 case 't': 772 if (::strncmp (var_name_begin, "thread.", strlen("thread.")) == 0) 773 { 774 if (exe_ctx && exe_ctx->thread) 775 { 776 var_name_begin += ::strlen ("thread."); 777 if (::strncmp (var_name_begin, "id}", strlen("id}")) == 0) 778 { 779 s.Printf("0x%4.4x", exe_ctx->thread->GetID()); 780 var_success = true; 781 } 782 else if (::strncmp (var_name_begin, "index}", strlen("index}")) == 0) 783 { 784 s.Printf("%u", exe_ctx->thread->GetIndexID()); 785 var_success = true; 786 } 787 else if (::strncmp (var_name_begin, "name}", strlen("name}")) == 0) 788 { 789 cstr = exe_ctx->thread->GetName(); 790 var_success = cstr && cstr[0]; 791 if (var_success) 792 s.PutCString(cstr); 793 } 794 else if (::strncmp (var_name_begin, "queue}", strlen("queue}")) == 0) 795 { 796 cstr = exe_ctx->thread->GetQueueName(); 797 var_success = cstr && cstr[0]; 798 if (var_success) 799 s.PutCString(cstr); 800 } 801 else if (::strncmp (var_name_begin, "stop-reason}", strlen("stop-reason}")) == 0) 802 { 803 StopInfoSP stop_info_sp = exe_ctx->thread->GetStopInfo (); 804 if (stop_info_sp) 805 { 806 cstr = stop_info_sp->GetDescription(); 807 if (cstr && cstr[0]) 808 { 809 s.PutCString(cstr); 810 var_success = true; 811 } 812 } 813 } 814 } 815 } 816 else if (::strncmp (var_name_begin, "target.", strlen("target.")) == 0) 817 { 818 Target *target = Target::GetTargetFromContexts (exe_ctx, sc); 819 if (target) 820 { 821 var_name_begin += ::strlen ("target."); 822 if (::strncmp (var_name_begin, "arch}", strlen("arch}")) == 0) 823 { 824 ArchSpec arch (target->GetArchitecture ()); 825 if (arch.IsValid()) 826 { 827 s.PutCString (arch.GetArchitectureName()); 828 var_success = true; 829 } 830 } 831 } 832 } 833 break; 834 835 836 case 'm': 837 if (::strncmp (var_name_begin, "module.", strlen("module.")) == 0) 838 { 839 if (sc && sc->module_sp.get()) 840 { 841 Module *module = sc->module_sp.get(); 842 var_name_begin += ::strlen ("module."); 843 844 if (::strncmp (var_name_begin, "file.", strlen("file.")) == 0) 845 { 846 if (module->GetFileSpec()) 847 { 848 var_name_begin += ::strlen ("file."); 849 850 if (::strncmp (var_name_begin, "basename}", strlen("basename}")) == 0) 851 { 852 format_file_spec.GetFilename() = module->GetFileSpec().GetFilename(); 853 var_success = format_file_spec; 854 } 855 else if (::strncmp (var_name_begin, "fullpath}", strlen("fullpath}")) == 0) 856 { 857 format_file_spec = module->GetFileSpec(); 858 var_success = format_file_spec; 859 } 860 } 861 } 862 } 863 } 864 break; 865 866 867 case 'f': 868 if (::strncmp (var_name_begin, "file.", strlen("file.")) == 0) 869 { 870 if (sc && sc->comp_unit != NULL) 871 { 872 var_name_begin += ::strlen ("file."); 873 874 if (::strncmp (var_name_begin, "basename}", strlen("basename}")) == 0) 875 { 876 format_file_spec.GetFilename() = sc->comp_unit->GetFilename(); 877 var_success = format_file_spec; 878 } 879 else if (::strncmp (var_name_begin, "fullpath}", strlen("fullpath}")) == 0) 880 { 881 format_file_spec = *sc->comp_unit; 882 var_success = format_file_spec; 883 } 884 } 885 } 886 else if (::strncmp (var_name_begin, "frame.", strlen("frame.")) == 0) 887 { 888 if (exe_ctx && exe_ctx->frame) 889 { 890 var_name_begin += ::strlen ("frame."); 891 if (::strncmp (var_name_begin, "index}", strlen("index}")) == 0) 892 { 893 s.Printf("%u", exe_ctx->frame->GetFrameIndex()); 894 var_success = true; 895 } 896 else if (::strncmp (var_name_begin, "pc}", strlen("pc}")) == 0) 897 { 898 reg_kind = eRegisterKindGeneric; 899 reg_num = LLDB_REGNUM_GENERIC_PC; 900 var_success = true; 901 } 902 else if (::strncmp (var_name_begin, "sp}", strlen("sp}")) == 0) 903 { 904 reg_kind = eRegisterKindGeneric; 905 reg_num = LLDB_REGNUM_GENERIC_SP; 906 var_success = true; 907 } 908 else if (::strncmp (var_name_begin, "fp}", strlen("fp}")) == 0) 909 { 910 reg_kind = eRegisterKindGeneric; 911 reg_num = LLDB_REGNUM_GENERIC_FP; 912 var_success = true; 913 } 914 else if (::strncmp (var_name_begin, "flags}", strlen("flags}")) == 0) 915 { 916 reg_kind = eRegisterKindGeneric; 917 reg_num = LLDB_REGNUM_GENERIC_FLAGS; 918 var_success = true; 919 } 920 else if (::strncmp (var_name_begin, "reg.", strlen ("reg.")) == 0) 921 { 922 reg_ctx = exe_ctx->frame->GetRegisterContext().get(); 923 if (reg_ctx) 924 { 925 var_name_begin += ::strlen ("reg."); 926 if (var_name_begin < var_name_end) 927 { 928 std::string reg_name (var_name_begin, var_name_end); 929 reg_info = reg_ctx->GetRegisterInfoByName (reg_name.c_str()); 930 if (reg_info) 931 var_success = true; 932 } 933 } 934 } 935 } 936 } 937 else if (::strncmp (var_name_begin, "function.", strlen("function.")) == 0) 938 { 939 if (sc && (sc->function != NULL || sc->symbol != NULL)) 940 { 941 var_name_begin += ::strlen ("function."); 942 if (::strncmp (var_name_begin, "id}", strlen("id}")) == 0) 943 { 944 if (sc->function) 945 s.Printf("function{0x%8.8x}", sc->function->GetID()); 946 else 947 s.Printf("symbol[%u]", sc->symbol->GetID()); 948 949 var_success = true; 950 } 951 else if (::strncmp (var_name_begin, "name}", strlen("name}")) == 0) 952 { 953 if (sc->function) 954 cstr = sc->function->GetName().AsCString (NULL); 955 else if (sc->symbol) 956 cstr = sc->symbol->GetName().AsCString (NULL); 957 if (cstr) 958 { 959 s.PutCString(cstr); 960 961 if (sc->block) 962 { 963 Block *inline_block = sc->block->GetContainingInlinedBlock (); 964 if (inline_block) 965 { 966 const InlineFunctionInfo *inline_info = sc->block->GetInlinedFunctionInfo(); 967 if (inline_info) 968 { 969 s.PutCString(" [inlined] "); 970 inline_info->GetName().Dump(&s); 971 } 972 } 973 } 974 var_success = true; 975 } 976 } 977 else if (::strncmp (var_name_begin, "addr-offset}", strlen("addr-offset}")) == 0) 978 { 979 var_success = addr != NULL; 980 if (var_success) 981 { 982 format_addr = *addr; 983 calculate_format_addr_function_offset = true; 984 } 985 } 986 else if (::strncmp (var_name_begin, "line-offset}", strlen("line-offset}")) == 0) 987 { 988 var_success = sc->line_entry.range.GetBaseAddress().IsValid(); 989 if (var_success) 990 { 991 format_addr = sc->line_entry.range.GetBaseAddress(); 992 calculate_format_addr_function_offset = true; 993 } 994 } 995 else if (::strncmp (var_name_begin, "pc-offset}", strlen("pc-offset}")) == 0) 996 { 997 var_success = exe_ctx->frame; 998 if (var_success) 999 { 1000 format_addr = exe_ctx->frame->GetFrameCodeAddress(); 1001 calculate_format_addr_function_offset = true; 1002 } 1003 } 1004 } 1005 } 1006 break; 1007 1008 case 'l': 1009 if (::strncmp (var_name_begin, "line.", strlen("line.")) == 0) 1010 { 1011 if (sc && sc->line_entry.IsValid()) 1012 { 1013 var_name_begin += ::strlen ("line."); 1014 if (::strncmp (var_name_begin, "file.", strlen("file.")) == 0) 1015 { 1016 var_name_begin += ::strlen ("file."); 1017 1018 if (::strncmp (var_name_begin, "basename}", strlen("basename}")) == 0) 1019 { 1020 format_file_spec.GetFilename() = sc->line_entry.file.GetFilename(); 1021 var_success = format_file_spec; 1022 } 1023 else if (::strncmp (var_name_begin, "fullpath}", strlen("fullpath}")) == 0) 1024 { 1025 format_file_spec = sc->line_entry.file; 1026 var_success = format_file_spec; 1027 } 1028 } 1029 else if (::strncmp (var_name_begin, "number}", strlen("number}")) == 0) 1030 { 1031 var_success = true; 1032 s.Printf("%u", sc->line_entry.line); 1033 } 1034 else if ((::strncmp (var_name_begin, "start-addr}", strlen("start-addr}")) == 0) || 1035 (::strncmp (var_name_begin, "end-addr}", strlen("end-addr}")) == 0)) 1036 { 1037 var_success = sc && sc->line_entry.range.GetBaseAddress().IsValid(); 1038 if (var_success) 1039 { 1040 format_addr = sc->line_entry.range.GetBaseAddress(); 1041 if (var_name_begin[0] == 'e') 1042 format_addr.Slide (sc->line_entry.range.GetByteSize()); 1043 } 1044 } 1045 } 1046 } 1047 break; 1048 } 1049 1050 if (var_success) 1051 { 1052 // If format addr is valid, then we need to print an address 1053 if (reg_num != LLDB_INVALID_REGNUM) 1054 { 1055 // We have a register value to display... 1056 if (reg_num == LLDB_REGNUM_GENERIC_PC && reg_kind == eRegisterKindGeneric) 1057 { 1058 format_addr = exe_ctx->frame->GetFrameCodeAddress(); 1059 } 1060 else 1061 { 1062 if (reg_ctx == NULL) 1063 reg_ctx = exe_ctx->frame->GetRegisterContext().get(); 1064 1065 if (reg_ctx) 1066 { 1067 if (reg_kind != kNumRegisterKinds) 1068 reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(reg_kind, reg_num); 1069 reg_info = reg_ctx->GetRegisterInfoAtIndex (reg_num); 1070 var_success = reg_info != NULL; 1071 } 1072 } 1073 } 1074 1075 if (reg_info != NULL) 1076 { 1077 DataExtractor reg_data; 1078 var_success = reg_ctx->ReadRegisterBytes (reg_info->kinds[eRegisterKindLLDB], reg_data); 1079 { 1080 reg_data.Dump(&s, 0, reg_info->format, reg_info->byte_size, 1, UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0); 1081 } 1082 } 1083 1084 if (format_file_spec) 1085 { 1086 s << format_file_spec; 1087 } 1088 1089 // If format addr is valid, then we need to print an address 1090 if (format_addr.IsValid()) 1091 { 1092 var_success = false; 1093 1094 if (calculate_format_addr_function_offset) 1095 { 1096 Address func_addr; 1097 1098 if (sc) 1099 { 1100 if (sc->function) 1101 { 1102 func_addr = sc->function->GetAddressRange().GetBaseAddress(); 1103 if (sc->block) 1104 { 1105 // Check to make sure we aren't in an inline 1106 // function. If we are, use the inline block 1107 // range that contains "format_addr" since 1108 // blocks can be discontiguous. 1109 Block *inline_block = sc->block->GetContainingInlinedBlock (); 1110 AddressRange inline_range; 1111 if (inline_block && inline_block->GetRangeContainingAddress (format_addr, inline_range)) 1112 func_addr = inline_range.GetBaseAddress(); 1113 } 1114 } 1115 else if (sc->symbol && sc->symbol->GetAddressRangePtr()) 1116 func_addr = sc->symbol->GetAddressRangePtr()->GetBaseAddress(); 1117 } 1118 1119 if (func_addr.IsValid()) 1120 { 1121 if (func_addr.GetSection() == format_addr.GetSection()) 1122 { 1123 addr_t func_file_addr = func_addr.GetFileAddress(); 1124 addr_t addr_file_addr = format_addr.GetFileAddress(); 1125 if (addr_file_addr > func_file_addr) 1126 s.Printf(" + %llu", addr_file_addr - func_file_addr); 1127 else if (addr_file_addr < func_file_addr) 1128 s.Printf(" - %llu", func_file_addr - addr_file_addr); 1129 var_success = true; 1130 } 1131 else 1132 { 1133 Target *target = Target::GetTargetFromContexts (exe_ctx, sc); 1134 if (target) 1135 { 1136 addr_t func_load_addr = func_addr.GetLoadAddress (target); 1137 addr_t addr_load_addr = format_addr.GetLoadAddress (target); 1138 if (addr_load_addr > func_load_addr) 1139 s.Printf(" + %llu", addr_load_addr - func_load_addr); 1140 else if (addr_load_addr < func_load_addr) 1141 s.Printf(" - %llu", func_load_addr - addr_load_addr); 1142 var_success = true; 1143 } 1144 } 1145 } 1146 } 1147 else 1148 { 1149 Target *target = Target::GetTargetFromContexts (exe_ctx, sc); 1150 addr_t vaddr = LLDB_INVALID_ADDRESS; 1151 if (exe_ctx && !target->GetSectionLoadList().IsEmpty()) 1152 vaddr = format_addr.GetLoadAddress (target); 1153 if (vaddr == LLDB_INVALID_ADDRESS) 1154 vaddr = format_addr.GetFileAddress (); 1155 1156 if (vaddr != LLDB_INVALID_ADDRESS) 1157 { 1158 int addr_width = target->GetArchitecture().GetAddressByteSize() * 2; 1159 if (addr_width == 0) 1160 addr_width = 16; 1161 s.Printf("0x%*.*llx", addr_width, addr_width, vaddr); 1162 var_success = true; 1163 } 1164 } 1165 } 1166 } 1167 1168 if (var_success == false) 1169 success = false; 1170 } 1171 p = var_name_end; 1172 } 1173 else 1174 break; 1175 } 1176 else 1177 { 1178 // We got a dollar sign with no '{' after it, it must just be a dollar sign 1179 s.PutChar(*p); 1180 } 1181 } 1182 else if (*p == '\\') 1183 { 1184 ++p; // skip the slash 1185 switch (*p) 1186 { 1187 case 'a': s.PutChar ('\a'); break; 1188 case 'b': s.PutChar ('\b'); break; 1189 case 'f': s.PutChar ('\f'); break; 1190 case 'n': s.PutChar ('\n'); break; 1191 case 'r': s.PutChar ('\r'); break; 1192 case 't': s.PutChar ('\t'); break; 1193 case 'v': s.PutChar ('\v'); break; 1194 case '\'': s.PutChar ('\''); break; 1195 case '\\': s.PutChar ('\\'); break; 1196 case '0': 1197 // 1 to 3 octal chars 1198 { 1199 // Make a string that can hold onto the initial zero char, 1200 // up to 3 octal digits, and a terminating NULL. 1201 char oct_str[5] = { 0, 0, 0, 0, 0 }; 1202 1203 int i; 1204 for (i=0; (p[i] >= '0' && p[i] <= '7') && i<4; ++i) 1205 oct_str[i] = p[i]; 1206 1207 // We don't want to consume the last octal character since 1208 // the main for loop will do this for us, so we advance p by 1209 // one less than i (even if i is zero) 1210 p += i - 1; 1211 unsigned long octal_value = ::strtoul (oct_str, NULL, 8); 1212 if (octal_value <= UINT8_MAX) 1213 { 1214 char octal_char = octal_value; 1215 s.Write (&octal_char, 1); 1216 } 1217 } 1218 break; 1219 1220 case 'x': 1221 // hex number in the format 1222 if (isxdigit(p[1])) 1223 { 1224 ++p; // Skip the 'x' 1225 1226 // Make a string that can hold onto two hex chars plus a 1227 // NULL terminator 1228 char hex_str[3] = { 0,0,0 }; 1229 hex_str[0] = *p; 1230 if (isxdigit(p[1])) 1231 { 1232 ++p; // Skip the first of the two hex chars 1233 hex_str[1] = *p; 1234 } 1235 1236 unsigned long hex_value = strtoul (hex_str, NULL, 16); 1237 if (hex_value <= UINT8_MAX) 1238 s.PutChar (hex_value); 1239 } 1240 else 1241 { 1242 s.PutChar('x'); 1243 } 1244 break; 1245 1246 default: 1247 // Just desensitize any other character by just printing what 1248 // came after the '\' 1249 s << *p; 1250 break; 1251 1252 } 1253 1254 } 1255 } 1256 if (end) 1257 *end = p; 1258 return success; 1259 } 1260 1261 #pragma mark Debugger::SettingsController 1262 1263 //-------------------------------------------------- 1264 // class Debugger::SettingsController 1265 //-------------------------------------------------- 1266 1267 Debugger::SettingsController::SettingsController () : 1268 UserSettingsController ("", lldb::UserSettingsControllerSP()) 1269 { 1270 m_default_settings.reset (new DebuggerInstanceSettings (*this, false, 1271 InstanceSettings::GetDefaultName().AsCString())); 1272 } 1273 1274 Debugger::SettingsController::~SettingsController () 1275 { 1276 } 1277 1278 1279 lldb::InstanceSettingsSP 1280 Debugger::SettingsController::CreateInstanceSettings (const char *instance_name) 1281 { 1282 DebuggerInstanceSettings *new_settings = new DebuggerInstanceSettings (*GetSettingsController(), 1283 false, instance_name); 1284 lldb::InstanceSettingsSP new_settings_sp (new_settings); 1285 return new_settings_sp; 1286 } 1287 1288 #pragma mark DebuggerInstanceSettings 1289 //-------------------------------------------------- 1290 // class DebuggerInstanceSettings 1291 //-------------------------------------------------- 1292 1293 DebuggerInstanceSettings::DebuggerInstanceSettings 1294 ( 1295 UserSettingsController &owner, 1296 bool live_instance, 1297 const char *name 1298 ) : 1299 InstanceSettings (owner, name ? name : InstanceSettings::InvalidName().AsCString(), live_instance), 1300 m_term_width (80), 1301 m_prompt (), 1302 m_frame_format (), 1303 m_thread_format (), 1304 m_script_lang (), 1305 m_use_external_editor (false), 1306 m_auto_confirm_on (false) 1307 { 1308 // CopyInstanceSettings is a pure virtual function in InstanceSettings; it therefore cannot be called 1309 // until the vtables for DebuggerInstanceSettings are properly set up, i.e. AFTER all the initializers. 1310 // For this reason it has to be called here, rather than in the initializer or in the parent constructor. 1311 // The same is true of CreateInstanceName(). 1312 1313 if (GetInstanceName() == InstanceSettings::InvalidName()) 1314 { 1315 ChangeInstanceName (std::string (CreateInstanceName().AsCString())); 1316 m_owner.RegisterInstanceSettings (this); 1317 } 1318 1319 if (live_instance) 1320 { 1321 const lldb::InstanceSettingsSP &pending_settings = m_owner.FindPendingSettings (m_instance_name); 1322 CopyInstanceSettings (pending_settings, false); 1323 } 1324 } 1325 1326 DebuggerInstanceSettings::DebuggerInstanceSettings (const DebuggerInstanceSettings &rhs) : 1327 InstanceSettings (*Debugger::GetSettingsController(), CreateInstanceName ().AsCString()), 1328 m_prompt (rhs.m_prompt), 1329 m_frame_format (rhs.m_frame_format), 1330 m_thread_format (rhs.m_thread_format), 1331 m_script_lang (rhs.m_script_lang), 1332 m_use_external_editor (rhs.m_use_external_editor), 1333 m_auto_confirm_on(rhs.m_auto_confirm_on) 1334 { 1335 const lldb::InstanceSettingsSP &pending_settings = m_owner.FindPendingSettings (m_instance_name); 1336 CopyInstanceSettings (pending_settings, false); 1337 m_owner.RemovePendingSettings (m_instance_name); 1338 } 1339 1340 DebuggerInstanceSettings::~DebuggerInstanceSettings () 1341 { 1342 } 1343 1344 DebuggerInstanceSettings& 1345 DebuggerInstanceSettings::operator= (const DebuggerInstanceSettings &rhs) 1346 { 1347 if (this != &rhs) 1348 { 1349 m_term_width = rhs.m_term_width; 1350 m_prompt = rhs.m_prompt; 1351 m_frame_format = rhs.m_frame_format; 1352 m_thread_format = rhs.m_thread_format; 1353 m_script_lang = rhs.m_script_lang; 1354 m_use_external_editor = rhs.m_use_external_editor; 1355 m_auto_confirm_on = rhs.m_auto_confirm_on; 1356 } 1357 1358 return *this; 1359 } 1360 1361 bool 1362 DebuggerInstanceSettings::ValidTermWidthValue (const char *value, Error err) 1363 { 1364 bool valid = false; 1365 1366 // Verify we have a value string. 1367 if (value == NULL || value[0] == '\0') 1368 { 1369 err.SetErrorString ("Missing value. Can't set terminal width without a value.\n"); 1370 } 1371 else 1372 { 1373 char *end = NULL; 1374 const uint32_t width = ::strtoul (value, &end, 0); 1375 1376 if (end && end[0] == '\0') 1377 { 1378 if (width >= 10 && width <= 1024) 1379 valid = true; 1380 else 1381 err.SetErrorString ("Invalid term-width value; value must be between 10 and 1024.\n"); 1382 } 1383 else 1384 err.SetErrorStringWithFormat ("'%s' is not a valid unsigned integer string.\n", value); 1385 } 1386 1387 return valid; 1388 } 1389 1390 1391 void 1392 DebuggerInstanceSettings::UpdateInstanceSettingsVariable (const ConstString &var_name, 1393 const char *index_value, 1394 const char *value, 1395 const ConstString &instance_name, 1396 const SettingEntry &entry, 1397 VarSetOperationType op, 1398 Error &err, 1399 bool pending) 1400 { 1401 1402 if (var_name == TermWidthVarName()) 1403 { 1404 if (ValidTermWidthValue (value, err)) 1405 { 1406 m_term_width = ::strtoul (value, NULL, 0); 1407 } 1408 } 1409 else if (var_name == PromptVarName()) 1410 { 1411 UserSettingsController::UpdateStringVariable (op, m_prompt, value, err); 1412 if (!pending) 1413 { 1414 // 'instance_name' is actually (probably) in the form '[<instance_name>]'; if so, we need to 1415 // strip off the brackets before passing it to BroadcastPromptChange. 1416 1417 std::string tmp_instance_name (instance_name.AsCString()); 1418 if ((tmp_instance_name[0] == '[') 1419 && (tmp_instance_name[instance_name.GetLength() - 1] == ']')) 1420 tmp_instance_name = tmp_instance_name.substr (1, instance_name.GetLength() - 2); 1421 ConstString new_name (tmp_instance_name.c_str()); 1422 1423 BroadcastPromptChange (new_name, m_prompt.c_str()); 1424 } 1425 } 1426 else if (var_name == GetFrameFormatName()) 1427 { 1428 UserSettingsController::UpdateStringVariable (op, m_frame_format, value, err); 1429 } 1430 else if (var_name == GetThreadFormatName()) 1431 { 1432 UserSettingsController::UpdateStringVariable (op, m_thread_format, value, err); 1433 } 1434 else if (var_name == ScriptLangVarName()) 1435 { 1436 bool success; 1437 m_script_lang = Args::StringToScriptLanguage (value, eScriptLanguageDefault, 1438 &success); 1439 } 1440 else if (var_name == UseExternalEditorVarName ()) 1441 { 1442 UserSettingsController::UpdateBooleanVariable (op, m_use_external_editor, value, err); 1443 } 1444 else if (var_name == AutoConfirmName ()) 1445 { 1446 UserSettingsController::UpdateBooleanVariable (op, m_auto_confirm_on, value, err); 1447 } 1448 } 1449 1450 bool 1451 DebuggerInstanceSettings::GetInstanceSettingsValue (const SettingEntry &entry, 1452 const ConstString &var_name, 1453 StringList &value, 1454 Error *err) 1455 { 1456 if (var_name == PromptVarName()) 1457 { 1458 value.AppendString (m_prompt.c_str(), m_prompt.size()); 1459 1460 } 1461 else if (var_name == ScriptLangVarName()) 1462 { 1463 value.AppendString (ScriptInterpreter::LanguageToString (m_script_lang).c_str()); 1464 } 1465 else if (var_name == TermWidthVarName()) 1466 { 1467 StreamString width_str; 1468 width_str.Printf ("%d", m_term_width); 1469 value.AppendString (width_str.GetData()); 1470 } 1471 else if (var_name == GetFrameFormatName ()) 1472 { 1473 value.AppendString(m_frame_format.c_str(), m_frame_format.size()); 1474 } 1475 else if (var_name == GetThreadFormatName ()) 1476 { 1477 value.AppendString(m_thread_format.c_str(), m_thread_format.size()); 1478 } 1479 else if (var_name == UseExternalEditorVarName()) 1480 { 1481 if (m_use_external_editor) 1482 value.AppendString ("true"); 1483 else 1484 value.AppendString ("false"); 1485 } 1486 else if (var_name == AutoConfirmName()) 1487 { 1488 if (m_auto_confirm_on) 1489 value.AppendString ("true"); 1490 else 1491 value.AppendString ("false"); 1492 } 1493 else 1494 { 1495 if (err) 1496 err->SetErrorStringWithFormat ("unrecognized variable name '%s'", var_name.AsCString()); 1497 return false; 1498 } 1499 return true; 1500 } 1501 1502 void 1503 DebuggerInstanceSettings::CopyInstanceSettings (const lldb::InstanceSettingsSP &new_settings, 1504 bool pending) 1505 { 1506 if (new_settings.get() == NULL) 1507 return; 1508 1509 DebuggerInstanceSettings *new_debugger_settings = (DebuggerInstanceSettings *) new_settings.get(); 1510 1511 m_prompt = new_debugger_settings->m_prompt; 1512 if (!pending) 1513 { 1514 // 'instance_name' is actually (probably) in the form '[<instance_name>]'; if so, we need to 1515 // strip off the brackets before passing it to BroadcastPromptChange. 1516 1517 std::string tmp_instance_name (m_instance_name.AsCString()); 1518 if ((tmp_instance_name[0] == '[') 1519 && (tmp_instance_name[m_instance_name.GetLength() - 1] == ']')) 1520 tmp_instance_name = tmp_instance_name.substr (1, m_instance_name.GetLength() - 2); 1521 ConstString new_name (tmp_instance_name.c_str()); 1522 1523 BroadcastPromptChange (new_name, m_prompt.c_str()); 1524 } 1525 m_frame_format = new_debugger_settings->m_frame_format; 1526 m_thread_format = new_debugger_settings->m_thread_format; 1527 m_term_width = new_debugger_settings->m_term_width; 1528 m_script_lang = new_debugger_settings->m_script_lang; 1529 m_use_external_editor = new_debugger_settings->m_use_external_editor; 1530 m_auto_confirm_on = new_debugger_settings->m_auto_confirm_on; 1531 } 1532 1533 1534 bool 1535 DebuggerInstanceSettings::BroadcastPromptChange (const ConstString &instance_name, const char *new_prompt) 1536 { 1537 std::string tmp_prompt; 1538 1539 if (new_prompt != NULL) 1540 { 1541 tmp_prompt = new_prompt ; 1542 int len = tmp_prompt.size(); 1543 if (len > 1 1544 && (tmp_prompt[0] == '\'' || tmp_prompt[0] == '"') 1545 && (tmp_prompt[len-1] == tmp_prompt[0])) 1546 { 1547 tmp_prompt = tmp_prompt.substr(1,len-2); 1548 } 1549 len = tmp_prompt.size(); 1550 if (tmp_prompt[len-1] != ' ') 1551 tmp_prompt.append(" "); 1552 } 1553 EventSP new_event_sp; 1554 new_event_sp.reset (new Event(CommandInterpreter::eBroadcastBitResetPrompt, 1555 new EventDataBytes (tmp_prompt.c_str()))); 1556 1557 if (instance_name.GetLength() != 0) 1558 { 1559 // Set prompt for a particular instance. 1560 Debugger *dbg = Debugger::FindDebuggerWithInstanceName (instance_name).get(); 1561 if (dbg != NULL) 1562 { 1563 dbg->GetCommandInterpreter().BroadcastEvent (new_event_sp); 1564 } 1565 } 1566 1567 return true; 1568 } 1569 1570 const ConstString 1571 DebuggerInstanceSettings::CreateInstanceName () 1572 { 1573 static int instance_count = 1; 1574 StreamString sstr; 1575 1576 sstr.Printf ("debugger_%d", instance_count); 1577 ++instance_count; 1578 1579 const ConstString ret_val (sstr.GetData()); 1580 1581 return ret_val; 1582 } 1583 1584 const ConstString & 1585 DebuggerInstanceSettings::PromptVarName () 1586 { 1587 static ConstString prompt_var_name ("prompt"); 1588 1589 return prompt_var_name; 1590 } 1591 1592 const ConstString & 1593 DebuggerInstanceSettings::GetFrameFormatName () 1594 { 1595 static ConstString prompt_var_name ("frame-format"); 1596 1597 return prompt_var_name; 1598 } 1599 1600 const ConstString & 1601 DebuggerInstanceSettings::GetThreadFormatName () 1602 { 1603 static ConstString prompt_var_name ("thread-format"); 1604 1605 return prompt_var_name; 1606 } 1607 1608 const ConstString & 1609 DebuggerInstanceSettings::ScriptLangVarName () 1610 { 1611 static ConstString script_lang_var_name ("script-lang"); 1612 1613 return script_lang_var_name; 1614 } 1615 1616 const ConstString & 1617 DebuggerInstanceSettings::TermWidthVarName () 1618 { 1619 static ConstString term_width_var_name ("term-width"); 1620 1621 return term_width_var_name; 1622 } 1623 1624 const ConstString & 1625 DebuggerInstanceSettings::UseExternalEditorVarName () 1626 { 1627 static ConstString use_external_editor_var_name ("use-external-editor"); 1628 1629 return use_external_editor_var_name; 1630 } 1631 1632 const ConstString & 1633 DebuggerInstanceSettings::AutoConfirmName () 1634 { 1635 static ConstString use_external_editor_var_name ("auto-confirm"); 1636 1637 return use_external_editor_var_name; 1638 } 1639 1640 //-------------------------------------------------- 1641 // SettingsController Variable Tables 1642 //-------------------------------------------------- 1643 1644 1645 SettingEntry 1646 Debugger::SettingsController::global_settings_table[] = 1647 { 1648 //{ "var-name", var-type, "default", enum-table, init'd, hidden, "help-text"}, 1649 // The Debugger level global table should always be empty; all Debugger settable variables should be instance 1650 // variables. 1651 { NULL, eSetVarTypeNone, NULL, NULL, 0, 0, NULL } 1652 }; 1653 1654 #define MODULE_WITH_FUNC "{ ${module.file.basename}{`${function.name}${function.pc-offset}}}" 1655 #define FILE_AND_LINE "{ at ${line.file.basename}:${line.number}}" 1656 1657 #define DEFAULT_THREAD_FORMAT "thread #${thread.index}: tid = ${thread.id}"\ 1658 "{, ${frame.pc}}"\ 1659 MODULE_WITH_FUNC\ 1660 FILE_AND_LINE\ 1661 "{, stop reason = ${thread.stop-reason}}"\ 1662 "\\n" 1663 1664 //#define DEFAULT_THREAD_FORMAT "thread #${thread.index}: tid = ${thread.id}"\ 1665 // "{, ${frame.pc}}"\ 1666 // MODULE_WITH_FUNC\ 1667 // FILE_AND_LINE\ 1668 // "{, stop reason = ${thread.stop-reason}}"\ 1669 // "{, name = ${thread.name}}"\ 1670 // "{, queue = ${thread.queue}}"\ 1671 // "\\n" 1672 1673 #define DEFAULT_FRAME_FORMAT "frame #${frame.index}: ${frame.pc}"\ 1674 MODULE_WITH_FUNC\ 1675 FILE_AND_LINE\ 1676 "\\n" 1677 1678 SettingEntry 1679 Debugger::SettingsController::instance_settings_table[] = 1680 { 1681 // NAME Setting variable type Default Enum Init'd Hidden Help 1682 // ======================= ======================= ====================== ==== ====== ====== ====================== 1683 { "frame-format", eSetVarTypeString, DEFAULT_FRAME_FORMAT, NULL, false, false, "The default frame format string to use when displaying thread information." }, 1684 { "prompt", eSetVarTypeString, "(lldb) ", NULL, false, false, "The debugger command line prompt displayed for the user." }, 1685 { "script-lang", eSetVarTypeString, "python", NULL, false, false, "The script language to be used for evaluating user-written scripts." }, 1686 { "term-width", eSetVarTypeInt, "80" , NULL, false, false, "The maximum number of columns to use for displaying text." }, 1687 { "thread-format", eSetVarTypeString, DEFAULT_THREAD_FORMAT, NULL, false, false, "The default thread format string to use when displaying thread information." }, 1688 { "use-external-editor", eSetVarTypeBoolean, "false", NULL, false, false, "Whether to use an external editor or not." }, 1689 { "auto-confirm", eSetVarTypeBoolean, "false", NULL, false, false, "If true all confirmation prompts will receive their default reply." }, 1690 { NULL, eSetVarTypeNone, NULL, NULL, false, false, NULL } 1691 }; 1692