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