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-python.h" 11 12 #include "lldb/Core/Debugger.h" 13 14 #include <map> 15 16 #include "clang/AST/DeclCXX.h" 17 #include "clang/AST/Type.h" 18 #include "llvm/ADT/StringRef.h" 19 20 #include "lldb/lldb-private.h" 21 #include "lldb/Core/ConnectionFileDescriptor.h" 22 #include "lldb/Core/Module.h" 23 #include "lldb/Core/PluginManager.h" 24 #include "lldb/Core/RegisterValue.h" 25 #include "lldb/Core/State.h" 26 #include "lldb/Core/StreamAsynchronousIO.h" 27 #include "lldb/Core/StreamCallback.h" 28 #include "lldb/Core/StreamFile.h" 29 #include "lldb/Core/StreamString.h" 30 #include "lldb/Core/StructuredData.h" 31 #include "lldb/Core/Timer.h" 32 #include "lldb/Core/ValueObject.h" 33 #include "lldb/Core/ValueObjectVariable.h" 34 #include "lldb/DataFormatters/DataVisualization.h" 35 #include "lldb/DataFormatters/FormatManager.h" 36 #include "lldb/DataFormatters/TypeSummary.h" 37 #include "lldb/Host/DynamicLibrary.h" 38 #include "lldb/Host/Terminal.h" 39 #include "lldb/Interpreter/CommandInterpreter.h" 40 #include "lldb/Interpreter/OptionValueSInt64.h" 41 #include "lldb/Interpreter/OptionValueString.h" 42 #include "lldb/Symbol/ClangASTContext.h" 43 #include "lldb/Symbol/CompileUnit.h" 44 #include "lldb/Symbol/Function.h" 45 #include "lldb/Symbol/Symbol.h" 46 #include "lldb/Symbol/VariableList.h" 47 #include "lldb/Target/TargetList.h" 48 #include "lldb/Target/Process.h" 49 #include "lldb/Target/RegisterContext.h" 50 #include "lldb/Target/SectionLoadList.h" 51 #include "lldb/Target/StopInfo.h" 52 #include "lldb/Target/Target.h" 53 #include "lldb/Target/Thread.h" 54 #include "lldb/Utility/AnsiTerminal.h" 55 56 using namespace lldb; 57 using namespace lldb_private; 58 59 60 static uint32_t g_shared_debugger_refcount = 0; 61 static lldb::user_id_t g_unique_id = 1; 62 63 #pragma mark Static Functions 64 65 static Mutex & 66 GetDebuggerListMutex () 67 { 68 static Mutex g_mutex(Mutex::eMutexTypeRecursive); 69 return g_mutex; 70 } 71 72 typedef std::vector<DebuggerSP> DebuggerList; 73 74 static DebuggerList & 75 GetDebuggerList() 76 { 77 // hide the static debugger list inside a singleton accessor to avoid 78 // global init contructors 79 static DebuggerList g_list; 80 return g_list; 81 } 82 83 OptionEnumValueElement 84 g_show_disassembly_enum_values[] = 85 { 86 { Debugger::eStopDisassemblyTypeNever, "never", "Never show disassembly when displaying a stop context."}, 87 { Debugger::eStopDisassemblyTypeNoSource, "no-source", "Show disassembly when there is no source information, or the source file is missing when displaying a stop context."}, 88 { Debugger::eStopDisassemblyTypeAlways, "always", "Always show disassembly when displaying a stop context."}, 89 { 0, NULL, NULL } 90 }; 91 92 OptionEnumValueElement 93 g_language_enumerators[] = 94 { 95 { eScriptLanguageNone, "none", "Disable scripting languages."}, 96 { eScriptLanguagePython, "python", "Select python as the default scripting language."}, 97 { eScriptLanguageDefault, "default", "Select the lldb default as the default scripting language."}, 98 { 0, NULL, NULL } 99 }; 100 101 #define MODULE_WITH_FUNC "{ ${module.file.basename}{`${function.name-with-args}${function.pc-offset}}}" 102 #define FILE_AND_LINE "{ at ${line.file.basename}:${line.number}}" 103 104 #define DEFAULT_THREAD_FORMAT "thread #${thread.index}: tid = ${thread.id%tid}"\ 105 "{, ${frame.pc}}"\ 106 MODULE_WITH_FUNC\ 107 FILE_AND_LINE\ 108 "{, name = '${thread.name}'}"\ 109 "{, queue = '${thread.queue}'}"\ 110 "{, activity = '${thread.info.activity.name}'}" \ 111 "{, ${thread.info.trace_messages} messages}" \ 112 "{, stop reason = ${thread.stop-reason}}"\ 113 "{\\nReturn value: ${thread.return-value}}"\ 114 "\\n" 115 116 #define DEFAULT_FRAME_FORMAT "frame #${frame.index}: ${frame.pc}"\ 117 MODULE_WITH_FUNC\ 118 FILE_AND_LINE\ 119 "\\n" 120 121 122 123 static PropertyDefinition 124 g_properties[] = 125 { 126 { "auto-confirm", OptionValue::eTypeBoolean, true, false, NULL, NULL, "If true all confirmation prompts will receive their default reply." }, 127 { "frame-format", OptionValue::eTypeString , true, 0 , DEFAULT_FRAME_FORMAT, NULL, "The default frame format string to use when displaying stack frame information for threads." }, 128 { "notify-void", OptionValue::eTypeBoolean, true, false, NULL, NULL, "Notify the user explicitly if an expression returns void (default: false)." }, 129 { "prompt", OptionValue::eTypeString , true, OptionValueString::eOptionEncodeCharacterEscapeSequences, "(lldb) ", NULL, "The debugger command line prompt displayed for the user." }, 130 { "script-lang", OptionValue::eTypeEnum , true, eScriptLanguagePython, NULL, g_language_enumerators, "The script language to be used for evaluating user-written scripts." }, 131 { "stop-disassembly-count", OptionValue::eTypeSInt64 , true, 4 , NULL, NULL, "The number of disassembly lines to show when displaying a stopped context." }, 132 { "stop-disassembly-display", OptionValue::eTypeEnum , true, Debugger::eStopDisassemblyTypeNoSource, NULL, g_show_disassembly_enum_values, "Control when to display disassembly when displaying a stopped context." }, 133 { "stop-line-count-after", OptionValue::eTypeSInt64 , true, 3 , NULL, NULL, "The number of sources lines to display that come after the current source line when displaying a stopped context." }, 134 { "stop-line-count-before", OptionValue::eTypeSInt64 , true, 3 , NULL, NULL, "The number of sources lines to display that come before the current source line when displaying a stopped context." }, 135 { "term-width", OptionValue::eTypeSInt64 , true, 80 , NULL, NULL, "The maximum number of columns to use for displaying text." }, 136 { "thread-format", OptionValue::eTypeString , true, 0 , DEFAULT_THREAD_FORMAT, NULL, "The default thread format string to use when displaying thread information." }, 137 { "use-external-editor", OptionValue::eTypeBoolean, true, false, NULL, NULL, "Whether to use an external editor or not." }, 138 { "use-color", OptionValue::eTypeBoolean, true, true , NULL, NULL, "Whether to use Ansi color codes or not." }, 139 { "auto-one-line-summaries", OptionValue::eTypeBoolean, true, true, NULL, NULL, "If true, LLDB will automatically display small structs in one-liner format (default: true)." }, 140 141 { NULL, OptionValue::eTypeInvalid, true, 0 , NULL, NULL, NULL } 142 }; 143 144 enum 145 { 146 ePropertyAutoConfirm = 0, 147 ePropertyFrameFormat, 148 ePropertyNotiftVoid, 149 ePropertyPrompt, 150 ePropertyScriptLanguage, 151 ePropertyStopDisassemblyCount, 152 ePropertyStopDisassemblyDisplay, 153 ePropertyStopLineCountAfter, 154 ePropertyStopLineCountBefore, 155 ePropertyTerminalWidth, 156 ePropertyThreadFormat, 157 ePropertyUseExternalEditor, 158 ePropertyUseColor, 159 ePropertyAutoOneLineSummaries 160 }; 161 162 Debugger::LoadPluginCallbackType Debugger::g_load_plugin_callback = NULL; 163 164 Error 165 Debugger::SetPropertyValue (const ExecutionContext *exe_ctx, 166 VarSetOperationType op, 167 const char *property_path, 168 const char *value) 169 { 170 bool is_load_script = strcmp(property_path,"target.load-script-from-symbol-file") == 0; 171 TargetSP target_sp; 172 LoadScriptFromSymFile load_script_old_value; 173 if (is_load_script && exe_ctx->GetTargetSP()) 174 { 175 target_sp = exe_ctx->GetTargetSP(); 176 load_script_old_value = target_sp->TargetProperties::GetLoadScriptFromSymbolFile(); 177 } 178 Error error (Properties::SetPropertyValue (exe_ctx, op, property_path, value)); 179 if (error.Success()) 180 { 181 // FIXME it would be nice to have "on-change" callbacks for properties 182 if (strcmp(property_path, g_properties[ePropertyPrompt].name) == 0) 183 { 184 const char *new_prompt = GetPrompt(); 185 std::string str = lldb_utility::ansi::FormatAnsiTerminalCodes (new_prompt, GetUseColor()); 186 if (str.length()) 187 new_prompt = str.c_str(); 188 GetCommandInterpreter().UpdatePrompt(new_prompt); 189 EventSP prompt_change_event_sp (new Event(CommandInterpreter::eBroadcastBitResetPrompt, new EventDataBytes (new_prompt))); 190 GetCommandInterpreter().BroadcastEvent (prompt_change_event_sp); 191 } 192 else if (strcmp(property_path, g_properties[ePropertyUseColor].name) == 0) 193 { 194 // use-color changed. Ping the prompt so it can reset the ansi terminal codes. 195 SetPrompt (GetPrompt()); 196 } 197 else if (is_load_script && target_sp && load_script_old_value == eLoadScriptFromSymFileWarn) 198 { 199 if (target_sp->TargetProperties::GetLoadScriptFromSymbolFile() == eLoadScriptFromSymFileTrue) 200 { 201 std::list<Error> errors; 202 StreamString feedback_stream; 203 if (!target_sp->LoadScriptingResources(errors,&feedback_stream)) 204 { 205 StreamFileSP stream_sp (GetErrorFile()); 206 if (stream_sp) 207 { 208 for (auto error : errors) 209 { 210 stream_sp->Printf("%s\n",error.AsCString()); 211 } 212 if (feedback_stream.GetSize()) 213 stream_sp->Printf("%s",feedback_stream.GetData()); 214 } 215 } 216 } 217 } 218 } 219 return error; 220 } 221 222 bool 223 Debugger::GetAutoConfirm () const 224 { 225 const uint32_t idx = ePropertyAutoConfirm; 226 return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0); 227 } 228 229 const char * 230 Debugger::GetFrameFormat() const 231 { 232 const uint32_t idx = ePropertyFrameFormat; 233 return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_properties[idx].default_cstr_value); 234 } 235 236 bool 237 Debugger::GetNotifyVoid () const 238 { 239 const uint32_t idx = ePropertyNotiftVoid; 240 return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0); 241 } 242 243 const char * 244 Debugger::GetPrompt() const 245 { 246 const uint32_t idx = ePropertyPrompt; 247 return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_properties[idx].default_cstr_value); 248 } 249 250 void 251 Debugger::SetPrompt(const char *p) 252 { 253 const uint32_t idx = ePropertyPrompt; 254 m_collection_sp->SetPropertyAtIndexAsString (NULL, idx, p); 255 const char *new_prompt = GetPrompt(); 256 std::string str = lldb_utility::ansi::FormatAnsiTerminalCodes (new_prompt, GetUseColor()); 257 if (str.length()) 258 new_prompt = str.c_str(); 259 GetCommandInterpreter().UpdatePrompt(new_prompt); 260 } 261 262 const char * 263 Debugger::GetThreadFormat() const 264 { 265 const uint32_t idx = ePropertyThreadFormat; 266 return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_properties[idx].default_cstr_value); 267 } 268 269 lldb::ScriptLanguage 270 Debugger::GetScriptLanguage() const 271 { 272 const uint32_t idx = ePropertyScriptLanguage; 273 return (lldb::ScriptLanguage)m_collection_sp->GetPropertyAtIndexAsEnumeration (NULL, idx, g_properties[idx].default_uint_value); 274 } 275 276 bool 277 Debugger::SetScriptLanguage (lldb::ScriptLanguage script_lang) 278 { 279 const uint32_t idx = ePropertyScriptLanguage; 280 return m_collection_sp->SetPropertyAtIndexAsEnumeration (NULL, idx, script_lang); 281 } 282 283 uint32_t 284 Debugger::GetTerminalWidth () const 285 { 286 const uint32_t idx = ePropertyTerminalWidth; 287 return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value); 288 } 289 290 bool 291 Debugger::SetTerminalWidth (uint32_t term_width) 292 { 293 const uint32_t idx = ePropertyTerminalWidth; 294 return m_collection_sp->SetPropertyAtIndexAsSInt64 (NULL, idx, term_width); 295 } 296 297 bool 298 Debugger::GetUseExternalEditor () const 299 { 300 const uint32_t idx = ePropertyUseExternalEditor; 301 return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0); 302 } 303 304 bool 305 Debugger::SetUseExternalEditor (bool b) 306 { 307 const uint32_t idx = ePropertyUseExternalEditor; 308 return m_collection_sp->SetPropertyAtIndexAsBoolean (NULL, idx, b); 309 } 310 311 bool 312 Debugger::GetUseColor () const 313 { 314 const uint32_t idx = ePropertyUseColor; 315 return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0); 316 } 317 318 bool 319 Debugger::SetUseColor (bool b) 320 { 321 const uint32_t idx = ePropertyUseColor; 322 bool ret = m_collection_sp->SetPropertyAtIndexAsBoolean (NULL, idx, b); 323 SetPrompt (GetPrompt()); 324 return ret; 325 } 326 327 uint32_t 328 Debugger::GetStopSourceLineCount (bool before) const 329 { 330 const uint32_t idx = before ? ePropertyStopLineCountBefore : ePropertyStopLineCountAfter; 331 return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value); 332 } 333 334 Debugger::StopDisassemblyType 335 Debugger::GetStopDisassemblyDisplay () const 336 { 337 const uint32_t idx = ePropertyStopDisassemblyDisplay; 338 return (Debugger::StopDisassemblyType)m_collection_sp->GetPropertyAtIndexAsEnumeration (NULL, idx, g_properties[idx].default_uint_value); 339 } 340 341 uint32_t 342 Debugger::GetDisassemblyLineCount () const 343 { 344 const uint32_t idx = ePropertyStopDisassemblyCount; 345 return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value); 346 } 347 348 bool 349 Debugger::GetAutoOneLineSummaries () const 350 { 351 const uint32_t idx = ePropertyAutoOneLineSummaries; 352 return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, true); 353 354 } 355 356 #pragma mark Debugger 357 358 //const DebuggerPropertiesSP & 359 //Debugger::GetSettings() const 360 //{ 361 // return m_properties_sp; 362 //} 363 // 364 365 int 366 Debugger::TestDebuggerRefCount () 367 { 368 return g_shared_debugger_refcount; 369 } 370 371 void 372 Debugger::Initialize (LoadPluginCallbackType load_plugin_callback) 373 { 374 g_load_plugin_callback = load_plugin_callback; 375 if (g_shared_debugger_refcount++ == 0) 376 lldb_private::Initialize(); 377 } 378 379 void 380 Debugger::Terminate () 381 { 382 if (g_shared_debugger_refcount > 0) 383 { 384 g_shared_debugger_refcount--; 385 if (g_shared_debugger_refcount == 0) 386 { 387 lldb_private::WillTerminate(); 388 lldb_private::Terminate(); 389 390 // Clear our master list of debugger objects 391 Mutex::Locker locker (GetDebuggerListMutex ()); 392 GetDebuggerList().clear(); 393 } 394 } 395 } 396 397 void 398 Debugger::SettingsInitialize () 399 { 400 Target::SettingsInitialize (); 401 } 402 403 void 404 Debugger::SettingsTerminate () 405 { 406 Target::SettingsTerminate (); 407 } 408 409 bool 410 Debugger::LoadPlugin (const FileSpec& spec, Error& error) 411 { 412 if (g_load_plugin_callback) 413 { 414 lldb::DynamicLibrarySP dynlib_sp = g_load_plugin_callback (shared_from_this(), spec, error); 415 if (dynlib_sp) 416 { 417 m_loaded_plugins.push_back(dynlib_sp); 418 return true; 419 } 420 } 421 else 422 { 423 // The g_load_plugin_callback is registered in SBDebugger::Initialize() 424 // and if the public API layer isn't available (code is linking against 425 // all of the internal LLDB static libraries), then we can't load plugins 426 error.SetErrorString("Public API layer is not available"); 427 } 428 return false; 429 } 430 431 static FileSpec::EnumerateDirectoryResult 432 LoadPluginCallback 433 ( 434 void *baton, 435 FileSpec::FileType file_type, 436 const FileSpec &file_spec 437 ) 438 { 439 Error error; 440 441 static ConstString g_dylibext("dylib"); 442 static ConstString g_solibext("so"); 443 444 if (!baton) 445 return FileSpec::eEnumerateDirectoryResultQuit; 446 447 Debugger *debugger = (Debugger*)baton; 448 449 // If we have a regular file, a symbolic link or unknown file type, try 450 // and process the file. We must handle unknown as sometimes the directory 451 // enumeration might be enumerating a file system that doesn't have correct 452 // file type information. 453 if (file_type == FileSpec::eFileTypeRegular || 454 file_type == FileSpec::eFileTypeSymbolicLink || 455 file_type == FileSpec::eFileTypeUnknown ) 456 { 457 FileSpec plugin_file_spec (file_spec); 458 plugin_file_spec.ResolvePath (); 459 460 if (plugin_file_spec.GetFileNameExtension() != g_dylibext && 461 plugin_file_spec.GetFileNameExtension() != g_solibext) 462 { 463 return FileSpec::eEnumerateDirectoryResultNext; 464 } 465 466 Error plugin_load_error; 467 debugger->LoadPlugin (plugin_file_spec, plugin_load_error); 468 469 return FileSpec::eEnumerateDirectoryResultNext; 470 } 471 472 else if (file_type == FileSpec::eFileTypeUnknown || 473 file_type == FileSpec::eFileTypeDirectory || 474 file_type == FileSpec::eFileTypeSymbolicLink ) 475 { 476 // Try and recurse into anything that a directory or symbolic link. 477 // We must also do this for unknown as sometimes the directory enumeration 478 // might be enurating a file system that doesn't have correct file type 479 // information. 480 return FileSpec::eEnumerateDirectoryResultEnter; 481 } 482 483 return FileSpec::eEnumerateDirectoryResultNext; 484 } 485 486 void 487 Debugger::InstanceInitialize () 488 { 489 FileSpec dir_spec; 490 const bool find_directories = true; 491 const bool find_files = true; 492 const bool find_other = true; 493 char dir_path[PATH_MAX]; 494 if (Host::GetLLDBPath (ePathTypeLLDBSystemPlugins, dir_spec)) 495 { 496 if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path))) 497 { 498 FileSpec::EnumerateDirectory (dir_path, 499 find_directories, 500 find_files, 501 find_other, 502 LoadPluginCallback, 503 this); 504 } 505 } 506 507 if (Host::GetLLDBPath (ePathTypeLLDBUserPlugins, dir_spec)) 508 { 509 if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path))) 510 { 511 FileSpec::EnumerateDirectory (dir_path, 512 find_directories, 513 find_files, 514 find_other, 515 LoadPluginCallback, 516 this); 517 } 518 } 519 520 PluginManager::DebuggerInitialize (*this); 521 } 522 523 DebuggerSP 524 Debugger::CreateInstance (lldb::LogOutputCallback log_callback, void *baton) 525 { 526 DebuggerSP debugger_sp (new Debugger(log_callback, baton)); 527 if (g_shared_debugger_refcount > 0) 528 { 529 Mutex::Locker locker (GetDebuggerListMutex ()); 530 GetDebuggerList().push_back(debugger_sp); 531 } 532 debugger_sp->InstanceInitialize (); 533 return debugger_sp; 534 } 535 536 void 537 Debugger::Destroy (DebuggerSP &debugger_sp) 538 { 539 if (debugger_sp.get() == NULL) 540 return; 541 542 debugger_sp->Clear(); 543 544 if (g_shared_debugger_refcount > 0) 545 { 546 Mutex::Locker locker (GetDebuggerListMutex ()); 547 DebuggerList &debugger_list = GetDebuggerList (); 548 DebuggerList::iterator pos, end = debugger_list.end(); 549 for (pos = debugger_list.begin (); pos != end; ++pos) 550 { 551 if ((*pos).get() == debugger_sp.get()) 552 { 553 debugger_list.erase (pos); 554 return; 555 } 556 } 557 } 558 } 559 560 DebuggerSP 561 Debugger::FindDebuggerWithInstanceName (const ConstString &instance_name) 562 { 563 DebuggerSP debugger_sp; 564 if (g_shared_debugger_refcount > 0) 565 { 566 Mutex::Locker locker (GetDebuggerListMutex ()); 567 DebuggerList &debugger_list = GetDebuggerList(); 568 DebuggerList::iterator pos, end = debugger_list.end(); 569 570 for (pos = debugger_list.begin(); pos != end; ++pos) 571 { 572 if ((*pos).get()->m_instance_name == instance_name) 573 { 574 debugger_sp = *pos; 575 break; 576 } 577 } 578 } 579 return debugger_sp; 580 } 581 582 TargetSP 583 Debugger::FindTargetWithProcessID (lldb::pid_t pid) 584 { 585 TargetSP target_sp; 586 if (g_shared_debugger_refcount > 0) 587 { 588 Mutex::Locker locker (GetDebuggerListMutex ()); 589 DebuggerList &debugger_list = GetDebuggerList(); 590 DebuggerList::iterator pos, end = debugger_list.end(); 591 for (pos = debugger_list.begin(); pos != end; ++pos) 592 { 593 target_sp = (*pos)->GetTargetList().FindTargetWithProcessID (pid); 594 if (target_sp) 595 break; 596 } 597 } 598 return target_sp; 599 } 600 601 TargetSP 602 Debugger::FindTargetWithProcess (Process *process) 603 { 604 TargetSP target_sp; 605 if (g_shared_debugger_refcount > 0) 606 { 607 Mutex::Locker locker (GetDebuggerListMutex ()); 608 DebuggerList &debugger_list = GetDebuggerList(); 609 DebuggerList::iterator pos, end = debugger_list.end(); 610 for (pos = debugger_list.begin(); pos != end; ++pos) 611 { 612 target_sp = (*pos)->GetTargetList().FindTargetWithProcess (process); 613 if (target_sp) 614 break; 615 } 616 } 617 return target_sp; 618 } 619 620 Debugger::Debugger (lldb::LogOutputCallback log_callback, void *baton) : 621 UserID (g_unique_id++), 622 Properties(OptionValuePropertiesSP(new OptionValueProperties())), 623 m_input_file_sp (new StreamFile (stdin, false)), 624 m_output_file_sp (new StreamFile (stdout, false)), 625 m_error_file_sp (new StreamFile (stderr, false)), 626 m_terminal_state (), 627 m_target_list (*this), 628 m_platform_list (), 629 m_listener ("lldb.Debugger"), 630 m_source_manager_ap(), 631 m_source_file_cache(), 632 m_command_interpreter_ap (new CommandInterpreter (*this, eScriptLanguageDefault, false)), 633 m_input_reader_stack (), 634 m_instance_name (), 635 m_loaded_plugins (), 636 m_event_handler_thread (LLDB_INVALID_HOST_THREAD), 637 m_io_handler_thread (LLDB_INVALID_HOST_THREAD) 638 { 639 char instance_cstr[256]; 640 snprintf(instance_cstr, sizeof(instance_cstr), "debugger_%d", (int)GetID()); 641 m_instance_name.SetCString(instance_cstr); 642 if (log_callback) 643 m_log_callback_stream_sp.reset (new StreamCallback (log_callback, baton)); 644 m_command_interpreter_ap->Initialize (); 645 // Always add our default platform to the platform list 646 PlatformSP default_platform_sp (Platform::GetDefaultPlatform()); 647 assert (default_platform_sp.get()); 648 m_platform_list.Append (default_platform_sp, true); 649 650 m_collection_sp->Initialize (g_properties); 651 m_collection_sp->AppendProperty (ConstString("target"), 652 ConstString("Settings specify to debugging targets."), 653 true, 654 Target::GetGlobalProperties()->GetValueProperties()); 655 if (m_command_interpreter_ap.get()) 656 { 657 m_collection_sp->AppendProperty (ConstString("interpreter"), 658 ConstString("Settings specify to the debugger's command interpreter."), 659 true, 660 m_command_interpreter_ap->GetValueProperties()); 661 } 662 OptionValueSInt64 *term_width = m_collection_sp->GetPropertyAtIndexAsOptionValueSInt64 (NULL, ePropertyTerminalWidth); 663 term_width->SetMinimumValue(10); 664 term_width->SetMaximumValue(1024); 665 666 // Turn off use-color if this is a dumb terminal. 667 const char *term = getenv ("TERM"); 668 if (term && !strcmp (term, "dumb")) 669 SetUseColor (false); 670 } 671 672 Debugger::~Debugger () 673 { 674 Clear(); 675 } 676 677 void 678 Debugger::Clear() 679 { 680 ClearIOHandlers(); 681 StopIOHandlerThread(); 682 StopEventHandlerThread(); 683 m_listener.Clear(); 684 int num_targets = m_target_list.GetNumTargets(); 685 for (int i = 0; i < num_targets; i++) 686 { 687 TargetSP target_sp (m_target_list.GetTargetAtIndex (i)); 688 if (target_sp) 689 { 690 ProcessSP process_sp (target_sp->GetProcessSP()); 691 if (process_sp) 692 process_sp->Finalize(); 693 target_sp->Destroy(); 694 } 695 } 696 BroadcasterManager::Clear (); 697 698 // Close the input file _before_ we close the input read communications class 699 // as it does NOT own the input file, our m_input_file does. 700 m_terminal_state.Clear(); 701 if (m_input_file_sp) 702 m_input_file_sp->GetFile().Close (); 703 704 m_command_interpreter_ap->Clear(); 705 } 706 707 bool 708 Debugger::GetCloseInputOnEOF () const 709 { 710 // return m_input_comm.GetCloseOnEOF(); 711 return false; 712 } 713 714 void 715 Debugger::SetCloseInputOnEOF (bool b) 716 { 717 // m_input_comm.SetCloseOnEOF(b); 718 } 719 720 bool 721 Debugger::GetAsyncExecution () 722 { 723 return !m_command_interpreter_ap->GetSynchronous(); 724 } 725 726 void 727 Debugger::SetAsyncExecution (bool async_execution) 728 { 729 m_command_interpreter_ap->SetSynchronous (!async_execution); 730 } 731 732 733 void 734 Debugger::SetInputFileHandle (FILE *fh, bool tranfer_ownership) 735 { 736 if (m_input_file_sp) 737 m_input_file_sp->GetFile().SetStream (fh, tranfer_ownership); 738 else 739 m_input_file_sp.reset (new StreamFile (fh, tranfer_ownership)); 740 741 File &in_file = m_input_file_sp->GetFile(); 742 if (in_file.IsValid() == false) 743 in_file.SetStream (stdin, true); 744 745 // Save away the terminal state if that is relevant, so that we can restore it in RestoreInputState. 746 SaveInputTerminalState (); 747 } 748 749 void 750 Debugger::SetOutputFileHandle (FILE *fh, bool tranfer_ownership) 751 { 752 if (m_output_file_sp) 753 m_output_file_sp->GetFile().SetStream (fh, tranfer_ownership); 754 else 755 m_output_file_sp.reset (new StreamFile (fh, tranfer_ownership)); 756 757 File &out_file = m_output_file_sp->GetFile(); 758 if (out_file.IsValid() == false) 759 out_file.SetStream (stdout, false); 760 761 // do not create the ScriptInterpreter just for setting the output file handle 762 // as the constructor will know how to do the right thing on its own 763 const bool can_create = false; 764 ScriptInterpreter* script_interpreter = GetCommandInterpreter().GetScriptInterpreter(can_create); 765 if (script_interpreter) 766 script_interpreter->ResetOutputFileHandle (fh); 767 } 768 769 void 770 Debugger::SetErrorFileHandle (FILE *fh, bool tranfer_ownership) 771 { 772 if (m_error_file_sp) 773 m_error_file_sp->GetFile().SetStream (fh, tranfer_ownership); 774 else 775 m_error_file_sp.reset (new StreamFile (fh, tranfer_ownership)); 776 777 File &err_file = m_error_file_sp->GetFile(); 778 if (err_file.IsValid() == false) 779 err_file.SetStream (stderr, false); 780 } 781 782 void 783 Debugger::SaveInputTerminalState () 784 { 785 if (m_input_file_sp) 786 { 787 File &in_file = m_input_file_sp->GetFile(); 788 if (in_file.GetDescriptor() != File::kInvalidDescriptor) 789 m_terminal_state.Save(in_file.GetDescriptor(), true); 790 } 791 } 792 793 void 794 Debugger::RestoreInputTerminalState () 795 { 796 m_terminal_state.Restore(); 797 } 798 799 ExecutionContext 800 Debugger::GetSelectedExecutionContext () 801 { 802 ExecutionContext exe_ctx; 803 TargetSP target_sp(GetSelectedTarget()); 804 exe_ctx.SetTargetSP (target_sp); 805 806 if (target_sp) 807 { 808 ProcessSP process_sp (target_sp->GetProcessSP()); 809 exe_ctx.SetProcessSP (process_sp); 810 if (process_sp && process_sp->IsRunning() == false) 811 { 812 ThreadSP thread_sp (process_sp->GetThreadList().GetSelectedThread()); 813 if (thread_sp) 814 { 815 exe_ctx.SetThreadSP (thread_sp); 816 exe_ctx.SetFrameSP (thread_sp->GetSelectedFrame()); 817 if (exe_ctx.GetFramePtr() == NULL) 818 exe_ctx.SetFrameSP (thread_sp->GetStackFrameAtIndex (0)); 819 } 820 } 821 } 822 return exe_ctx; 823 } 824 825 void 826 Debugger::DispatchInputInterrupt () 827 { 828 Mutex::Locker locker (m_input_reader_stack.GetMutex()); 829 IOHandlerSP reader_sp (m_input_reader_stack.Top()); 830 if (reader_sp) 831 reader_sp->Interrupt(); 832 } 833 834 void 835 Debugger::DispatchInputEndOfFile () 836 { 837 Mutex::Locker locker (m_input_reader_stack.GetMutex()); 838 IOHandlerSP reader_sp (m_input_reader_stack.Top()); 839 if (reader_sp) 840 reader_sp->GotEOF(); 841 } 842 843 void 844 Debugger::ClearIOHandlers () 845 { 846 // The bottom input reader should be the main debugger input reader. We do not want to close that one here. 847 Mutex::Locker locker (m_input_reader_stack.GetMutex()); 848 while (m_input_reader_stack.GetSize() > 1) 849 { 850 IOHandlerSP reader_sp (m_input_reader_stack.Top()); 851 if (reader_sp) 852 { 853 m_input_reader_stack.Pop(); 854 reader_sp->SetIsDone(true); 855 reader_sp->Cancel(); 856 } 857 } 858 } 859 860 void 861 Debugger::ExecuteIOHanders() 862 { 863 864 while (1) 865 { 866 IOHandlerSP reader_sp(m_input_reader_stack.Top()); 867 if (!reader_sp) 868 break; 869 870 reader_sp->Activate(); 871 reader_sp->Run(); 872 reader_sp->Deactivate(); 873 874 // Remove all input readers that are done from the top of the stack 875 while (1) 876 { 877 IOHandlerSP top_reader_sp = m_input_reader_stack.Top(); 878 if (top_reader_sp && top_reader_sp->GetIsDone()) 879 m_input_reader_stack.Pop(); 880 else 881 break; 882 } 883 } 884 ClearIOHandlers(); 885 } 886 887 bool 888 Debugger::IsTopIOHandler (const lldb::IOHandlerSP& reader_sp) 889 { 890 return m_input_reader_stack.IsTop (reader_sp); 891 } 892 893 894 ConstString 895 Debugger::GetTopIOHandlerControlSequence(char ch) 896 { 897 return m_input_reader_stack.GetTopIOHandlerControlSequence (ch); 898 } 899 900 void 901 Debugger::RunIOHandler (const IOHandlerSP& reader_sp) 902 { 903 Mutex::Locker locker (m_input_reader_stack.GetMutex()); 904 PushIOHandler (reader_sp); 905 906 IOHandlerSP top_reader_sp = reader_sp; 907 while (top_reader_sp) 908 { 909 top_reader_sp->Activate(); 910 top_reader_sp->Run(); 911 top_reader_sp->Deactivate(); 912 913 if (top_reader_sp.get() == reader_sp.get()) 914 { 915 if (PopIOHandler (reader_sp)) 916 break; 917 } 918 919 while (1) 920 { 921 top_reader_sp = m_input_reader_stack.Top(); 922 if (top_reader_sp && top_reader_sp->GetIsDone()) 923 m_input_reader_stack.Pop(); 924 else 925 break; 926 } 927 } 928 } 929 930 void 931 Debugger::AdoptTopIOHandlerFilesIfInvalid (StreamFileSP &in, StreamFileSP &out, StreamFileSP &err) 932 { 933 // Before an IOHandler runs, it must have in/out/err streams. 934 // This function is called when one ore more of the streams 935 // are NULL. We use the top input reader's in/out/err streams, 936 // or fall back to the debugger file handles, or we fall back 937 // onto stdin/stdout/stderr as a last resort. 938 939 Mutex::Locker locker (m_input_reader_stack.GetMutex()); 940 IOHandlerSP top_reader_sp (m_input_reader_stack.Top()); 941 // If no STDIN has been set, then set it appropriately 942 if (!in) 943 { 944 if (top_reader_sp) 945 in = top_reader_sp->GetInputStreamFile(); 946 else 947 in = GetInputFile(); 948 949 // If there is nothing, use stdin 950 if (!in) 951 in = StreamFileSP(new StreamFile(stdin, false)); 952 } 953 // If no STDOUT has been set, then set it appropriately 954 if (!out) 955 { 956 if (top_reader_sp) 957 out = top_reader_sp->GetOutputStreamFile(); 958 else 959 out = GetOutputFile(); 960 961 // If there is nothing, use stdout 962 if (!out) 963 out = StreamFileSP(new StreamFile(stdout, false)); 964 } 965 // If no STDERR has been set, then set it appropriately 966 if (!err) 967 { 968 if (top_reader_sp) 969 err = top_reader_sp->GetErrorStreamFile(); 970 else 971 err = GetErrorFile(); 972 973 // If there is nothing, use stderr 974 if (!err) 975 err = StreamFileSP(new StreamFile(stdout, false)); 976 977 } 978 } 979 980 void 981 Debugger::PushIOHandler (const IOHandlerSP& reader_sp) 982 { 983 if (!reader_sp) 984 return; 985 986 // Got the current top input reader... 987 IOHandlerSP top_reader_sp (m_input_reader_stack.Top()); 988 989 // Don't push the same IO handler twice... 990 if (reader_sp.get() != top_reader_sp.get()) 991 { 992 // Push our new input reader 993 m_input_reader_stack.Push (reader_sp); 994 995 // Interrupt the top input reader to it will exit its Run() function 996 // and let this new input reader take over 997 if (top_reader_sp) 998 top_reader_sp->Deactivate(); 999 } 1000 } 1001 1002 bool 1003 Debugger::PopIOHandler (const IOHandlerSP& pop_reader_sp) 1004 { 1005 bool result = false; 1006 1007 Mutex::Locker locker (m_input_reader_stack.GetMutex()); 1008 1009 // The reader on the stop of the stack is done, so let the next 1010 // read on the stack referesh its prompt and if there is one... 1011 if (!m_input_reader_stack.IsEmpty()) 1012 { 1013 IOHandlerSP reader_sp(m_input_reader_stack.Top()); 1014 1015 if (!pop_reader_sp || pop_reader_sp.get() == reader_sp.get()) 1016 { 1017 reader_sp->Deactivate(); 1018 reader_sp->Cancel(); 1019 m_input_reader_stack.Pop (); 1020 1021 reader_sp = m_input_reader_stack.Top(); 1022 if (reader_sp) 1023 reader_sp->Activate(); 1024 1025 result = true; 1026 } 1027 } 1028 return result; 1029 } 1030 1031 bool 1032 Debugger::HideTopIOHandler() 1033 { 1034 Mutex::Locker locker; 1035 1036 if (locker.TryLock(m_input_reader_stack.GetMutex())) 1037 { 1038 IOHandlerSP reader_sp(m_input_reader_stack.Top()); 1039 if (reader_sp) 1040 reader_sp->Hide(); 1041 return true; 1042 } 1043 return false; 1044 } 1045 1046 void 1047 Debugger::RefreshTopIOHandler() 1048 { 1049 IOHandlerSP reader_sp(m_input_reader_stack.Top()); 1050 if (reader_sp) 1051 reader_sp->Refresh(); 1052 } 1053 1054 1055 StreamSP 1056 Debugger::GetAsyncOutputStream () 1057 { 1058 return StreamSP (new StreamAsynchronousIO (GetCommandInterpreter(), 1059 CommandInterpreter::eBroadcastBitAsynchronousOutputData)); 1060 } 1061 1062 StreamSP 1063 Debugger::GetAsyncErrorStream () 1064 { 1065 return StreamSP (new StreamAsynchronousIO (GetCommandInterpreter(), 1066 CommandInterpreter::eBroadcastBitAsynchronousErrorData)); 1067 } 1068 1069 size_t 1070 Debugger::GetNumDebuggers() 1071 { 1072 if (g_shared_debugger_refcount > 0) 1073 { 1074 Mutex::Locker locker (GetDebuggerListMutex ()); 1075 return GetDebuggerList().size(); 1076 } 1077 return 0; 1078 } 1079 1080 lldb::DebuggerSP 1081 Debugger::GetDebuggerAtIndex (size_t index) 1082 { 1083 DebuggerSP debugger_sp; 1084 1085 if (g_shared_debugger_refcount > 0) 1086 { 1087 Mutex::Locker locker (GetDebuggerListMutex ()); 1088 DebuggerList &debugger_list = GetDebuggerList(); 1089 1090 if (index < debugger_list.size()) 1091 debugger_sp = debugger_list[index]; 1092 } 1093 1094 return debugger_sp; 1095 } 1096 1097 DebuggerSP 1098 Debugger::FindDebuggerWithID (lldb::user_id_t id) 1099 { 1100 DebuggerSP debugger_sp; 1101 1102 if (g_shared_debugger_refcount > 0) 1103 { 1104 Mutex::Locker locker (GetDebuggerListMutex ()); 1105 DebuggerList &debugger_list = GetDebuggerList(); 1106 DebuggerList::iterator pos, end = debugger_list.end(); 1107 for (pos = debugger_list.begin(); pos != end; ++pos) 1108 { 1109 if ((*pos).get()->GetID() == id) 1110 { 1111 debugger_sp = *pos; 1112 break; 1113 } 1114 } 1115 } 1116 return debugger_sp; 1117 } 1118 1119 #if 0 1120 static void 1121 TestPromptFormats (StackFrame *frame) 1122 { 1123 if (frame == NULL) 1124 return; 1125 1126 StreamString s; 1127 const char *prompt_format = 1128 "{addr = '${addr}'\n}" 1129 "{process.id = '${process.id}'\n}" 1130 "{process.name = '${process.name}'\n}" 1131 "{process.file.basename = '${process.file.basename}'\n}" 1132 "{process.file.fullpath = '${process.file.fullpath}'\n}" 1133 "{thread.id = '${thread.id}'\n}" 1134 "{thread.index = '${thread.index}'\n}" 1135 "{thread.name = '${thread.name}'\n}" 1136 "{thread.queue = '${thread.queue}'\n}" 1137 "{thread.stop-reason = '${thread.stop-reason}'\n}" 1138 "{target.arch = '${target.arch}'\n}" 1139 "{module.file.basename = '${module.file.basename}'\n}" 1140 "{module.file.fullpath = '${module.file.fullpath}'\n}" 1141 "{file.basename = '${file.basename}'\n}" 1142 "{file.fullpath = '${file.fullpath}'\n}" 1143 "{frame.index = '${frame.index}'\n}" 1144 "{frame.pc = '${frame.pc}'\n}" 1145 "{frame.sp = '${frame.sp}'\n}" 1146 "{frame.fp = '${frame.fp}'\n}" 1147 "{frame.flags = '${frame.flags}'\n}" 1148 "{frame.reg.rdi = '${frame.reg.rdi}'\n}" 1149 "{frame.reg.rip = '${frame.reg.rip}'\n}" 1150 "{frame.reg.rsp = '${frame.reg.rsp}'\n}" 1151 "{frame.reg.rbp = '${frame.reg.rbp}'\n}" 1152 "{frame.reg.rflags = '${frame.reg.rflags}'\n}" 1153 "{frame.reg.xmm0 = '${frame.reg.xmm0}'\n}" 1154 "{frame.reg.carp = '${frame.reg.carp}'\n}" 1155 "{function.id = '${function.id}'\n}" 1156 "{function.name = '${function.name}'\n}" 1157 "{function.name-with-args = '${function.name-with-args}'\n}" 1158 "{function.addr-offset = '${function.addr-offset}'\n}" 1159 "{function.line-offset = '${function.line-offset}'\n}" 1160 "{function.pc-offset = '${function.pc-offset}'\n}" 1161 "{line.file.basename = '${line.file.basename}'\n}" 1162 "{line.file.fullpath = '${line.file.fullpath}'\n}" 1163 "{line.number = '${line.number}'\n}" 1164 "{line.start-addr = '${line.start-addr}'\n}" 1165 "{line.end-addr = '${line.end-addr}'\n}" 1166 ; 1167 1168 SymbolContext sc (frame->GetSymbolContext(eSymbolContextEverything)); 1169 ExecutionContext exe_ctx; 1170 frame->CalculateExecutionContext(exe_ctx); 1171 if (Debugger::FormatPrompt (prompt_format, &sc, &exe_ctx, &sc.line_entry.range.GetBaseAddress(), s)) 1172 { 1173 printf("%s\n", s.GetData()); 1174 } 1175 else 1176 { 1177 printf ("what we got: %s\n", s.GetData()); 1178 } 1179 } 1180 #endif 1181 1182 static bool 1183 ScanFormatDescriptor (const char* var_name_begin, 1184 const char* var_name_end, 1185 const char** var_name_final, 1186 const char** percent_position, 1187 Format* custom_format, 1188 ValueObject::ValueObjectRepresentationStyle* val_obj_display) 1189 { 1190 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES)); 1191 *percent_position = ::strchr(var_name_begin,'%'); 1192 if (!*percent_position || *percent_position > var_name_end) 1193 { 1194 if (log) 1195 log->Printf("[ScanFormatDescriptor] no format descriptor in string, skipping"); 1196 *var_name_final = var_name_end; 1197 } 1198 else 1199 { 1200 *var_name_final = *percent_position; 1201 std::string format_name(*var_name_final+1, var_name_end-*var_name_final-1); 1202 if (log) 1203 log->Printf("[ScanFormatDescriptor] parsing %s as a format descriptor", format_name.c_str()); 1204 if ( !FormatManager::GetFormatFromCString(format_name.c_str(), 1205 true, 1206 *custom_format) ) 1207 { 1208 if (log) 1209 log->Printf("[ScanFormatDescriptor] %s is an unknown format", format_name.c_str()); 1210 1211 switch (format_name.front()) 1212 { 1213 case '@': // if this is an @ sign, print ObjC description 1214 *val_obj_display = ValueObject::eValueObjectRepresentationStyleLanguageSpecific; 1215 break; 1216 case 'V': // if this is a V, print the value using the default format 1217 *val_obj_display = ValueObject::eValueObjectRepresentationStyleValue; 1218 break; 1219 case 'L': // if this is an L, print the location of the value 1220 *val_obj_display = ValueObject::eValueObjectRepresentationStyleLocation; 1221 break; 1222 case 'S': // if this is an S, print the summary after all 1223 *val_obj_display = ValueObject::eValueObjectRepresentationStyleSummary; 1224 break; 1225 case '#': // if this is a '#', print the number of children 1226 *val_obj_display = ValueObject::eValueObjectRepresentationStyleChildrenCount; 1227 break; 1228 case 'T': // if this is a 'T', print the type 1229 *val_obj_display = ValueObject::eValueObjectRepresentationStyleType; 1230 break; 1231 case 'N': // if this is a 'N', print the name 1232 *val_obj_display = ValueObject::eValueObjectRepresentationStyleName; 1233 break; 1234 case '>': // if this is a '>', print the name 1235 *val_obj_display = ValueObject::eValueObjectRepresentationStyleExpressionPath; 1236 break; 1237 default: 1238 if (log) 1239 log->Printf("ScanFormatDescriptor] %s is an error, leaving the previous value alone", format_name.c_str()); 1240 break; 1241 } 1242 } 1243 // a good custom format tells us to print the value using it 1244 else 1245 { 1246 if (log) 1247 log->Printf("[ScanFormatDescriptor] will display value for this VO"); 1248 *val_obj_display = ValueObject::eValueObjectRepresentationStyleValue; 1249 } 1250 } 1251 if (log) 1252 log->Printf("[ScanFormatDescriptor] final format description outcome: custom_format = %d, val_obj_display = %d", 1253 *custom_format, 1254 *val_obj_display); 1255 return true; 1256 } 1257 1258 static bool 1259 ScanBracketedRange (const char* var_name_begin, 1260 const char* var_name_end, 1261 const char* var_name_final, 1262 const char** open_bracket_position, 1263 const char** separator_position, 1264 const char** close_bracket_position, 1265 const char** var_name_final_if_array_range, 1266 int64_t* index_lower, 1267 int64_t* index_higher) 1268 { 1269 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES)); 1270 *open_bracket_position = ::strchr(var_name_begin,'['); 1271 if (*open_bracket_position && *open_bracket_position < var_name_final) 1272 { 1273 *separator_position = ::strchr(*open_bracket_position,'-'); // might be NULL if this is a simple var[N] bitfield 1274 *close_bracket_position = ::strchr(*open_bracket_position,']'); 1275 // as usual, we assume that [] will come before % 1276 //printf("trying to expand a []\n"); 1277 *var_name_final_if_array_range = *open_bracket_position; 1278 if (*close_bracket_position - *open_bracket_position == 1) 1279 { 1280 if (log) 1281 log->Printf("[ScanBracketedRange] '[]' detected.. going from 0 to end of data"); 1282 *index_lower = 0; 1283 } 1284 else if (*separator_position == NULL || *separator_position > var_name_end) 1285 { 1286 char *end = NULL; 1287 *index_lower = ::strtoul (*open_bracket_position+1, &end, 0); 1288 *index_higher = *index_lower; 1289 if (log) 1290 log->Printf("[ScanBracketedRange] [%" PRId64 "] detected, high index is same", *index_lower); 1291 } 1292 else if (*close_bracket_position && *close_bracket_position < var_name_end) 1293 { 1294 char *end = NULL; 1295 *index_lower = ::strtoul (*open_bracket_position+1, &end, 0); 1296 *index_higher = ::strtoul (*separator_position+1, &end, 0); 1297 if (log) 1298 log->Printf("[ScanBracketedRange] [%" PRId64 "-%" PRId64 "] detected", *index_lower, *index_higher); 1299 } 1300 else 1301 { 1302 if (log) 1303 log->Printf("[ScanBracketedRange] expression is erroneous, cannot extract indices out of it"); 1304 return false; 1305 } 1306 if (*index_lower > *index_higher && *index_higher > 0) 1307 { 1308 if (log) 1309 log->Printf("[ScanBracketedRange] swapping indices"); 1310 int64_t temp = *index_lower; 1311 *index_lower = *index_higher; 1312 *index_higher = temp; 1313 } 1314 } 1315 else if (log) 1316 log->Printf("[ScanBracketedRange] no bracketed range, skipping entirely"); 1317 return true; 1318 } 1319 1320 template <typename T> 1321 static bool RunScriptFormatKeyword(Stream &s, ScriptInterpreter *script_interpreter, T t, const std::string& script_name) 1322 { 1323 if (script_interpreter) 1324 { 1325 Error script_error; 1326 std::string script_output; 1327 1328 if (script_interpreter->RunScriptFormatKeyword(script_name.c_str(), t, script_output, script_error) && script_error.Success()) 1329 { 1330 s.Printf("%s", script_output.c_str()); 1331 return true; 1332 } 1333 else 1334 { 1335 s.Printf("<error: %s>",script_error.AsCString()); 1336 } 1337 } 1338 return false; 1339 } 1340 1341 static ValueObjectSP 1342 ExpandIndexedExpression (ValueObject* valobj, 1343 size_t index, 1344 StackFrame* frame, 1345 bool deref_pointer) 1346 { 1347 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES)); 1348 const char* ptr_deref_format = "[%d]"; 1349 std::string ptr_deref_buffer(10,0); 1350 ::sprintf(&ptr_deref_buffer[0], ptr_deref_format, index); 1351 if (log) 1352 log->Printf("[ExpandIndexedExpression] name to deref: %s",ptr_deref_buffer.c_str()); 1353 const char* first_unparsed; 1354 ValueObject::GetValueForExpressionPathOptions options; 1355 ValueObject::ExpressionPathEndResultType final_value_type; 1356 ValueObject::ExpressionPathScanEndReason reason_to_stop; 1357 ValueObject::ExpressionPathAftermath what_next = (deref_pointer ? ValueObject::eExpressionPathAftermathDereference : ValueObject::eExpressionPathAftermathNothing); 1358 ValueObjectSP item = valobj->GetValueForExpressionPath (ptr_deref_buffer.c_str(), 1359 &first_unparsed, 1360 &reason_to_stop, 1361 &final_value_type, 1362 options, 1363 &what_next); 1364 if (!item) 1365 { 1366 if (log) 1367 log->Printf("[ExpandIndexedExpression] ERROR: unparsed portion = %s, why stopping = %d," 1368 " final_value_type %d", 1369 first_unparsed, reason_to_stop, final_value_type); 1370 } 1371 else 1372 { 1373 if (log) 1374 log->Printf("[ExpandIndexedExpression] ALL RIGHT: unparsed portion = %s, why stopping = %d," 1375 " final_value_type %d", 1376 first_unparsed, reason_to_stop, final_value_type); 1377 } 1378 return item; 1379 } 1380 1381 static inline bool 1382 IsToken(const char *var_name_begin, const char *var) 1383 { 1384 return (::strncmp (var_name_begin, var, strlen(var)) == 0); 1385 } 1386 1387 static bool 1388 IsTokenWithFormat(const char *var_name_begin, const char *var, std::string &format, const char *default_format, 1389 const ExecutionContext *exe_ctx_ptr, const SymbolContext *sc_ptr) 1390 { 1391 int var_len = strlen(var); 1392 if (::strncmp (var_name_begin, var, var_len) == 0) 1393 { 1394 var_name_begin += var_len; 1395 if (*var_name_begin == '}') 1396 { 1397 format = default_format; 1398 return true; 1399 } 1400 else if (*var_name_begin == '%') 1401 { 1402 // Allow format specifiers: x|X|u with optional width specifiers. 1403 // ${thread.id%x} ; hex 1404 // ${thread.id%X} ; uppercase hex 1405 // ${thread.id%u} ; unsigned decimal 1406 // ${thread.id%8.8X} ; width.precision + specifier 1407 // ${thread.id%tid} ; unsigned on FreeBSD/Linux, otherwise default_format (0x%4.4x for thread.id) 1408 int dot_count = 0; 1409 const char *specifier = NULL; 1410 int width_precision_length = 0; 1411 const char *width_precision = ++var_name_begin; 1412 while (isdigit(*var_name_begin) || *var_name_begin == '.') 1413 { 1414 dot_count += (*var_name_begin == '.'); 1415 if (dot_count > 1) 1416 break; 1417 var_name_begin++; 1418 width_precision_length++; 1419 } 1420 1421 if (IsToken (var_name_begin, "tid}")) 1422 { 1423 Target *target = Target::GetTargetFromContexts (exe_ctx_ptr, sc_ptr); 1424 if (target) 1425 { 1426 ArchSpec arch (target->GetArchitecture ()); 1427 llvm::Triple::OSType ostype = arch.IsValid() ? arch.GetTriple().getOS() : llvm::Triple::UnknownOS; 1428 if ((ostype == llvm::Triple::FreeBSD) || (ostype == llvm::Triple::Linux)) 1429 specifier = PRIu64; 1430 } 1431 if (!specifier) 1432 { 1433 format = default_format; 1434 return true; 1435 } 1436 } 1437 else if (IsToken (var_name_begin, "x}")) 1438 specifier = PRIx64; 1439 else if (IsToken (var_name_begin, "X}")) 1440 specifier = PRIX64; 1441 else if (IsToken (var_name_begin, "u}")) 1442 specifier = PRIu64; 1443 1444 if (specifier) 1445 { 1446 format = "%"; 1447 if (width_precision_length) 1448 format += std::string(width_precision, width_precision_length); 1449 format += specifier; 1450 return true; 1451 } 1452 } 1453 } 1454 return false; 1455 } 1456 1457 // Find information for the "thread.info.*" specifiers in a format string 1458 static bool 1459 FormatThreadExtendedInfoRecurse 1460 ( 1461 const char *var_name_begin, 1462 StructuredData::ObjectSP thread_info_dictionary, 1463 const SymbolContext *sc, 1464 const ExecutionContext *exe_ctx, 1465 Stream &s 1466 ) 1467 { 1468 bool var_success = false; 1469 std::string token_format; 1470 1471 llvm::StringRef var_name(var_name_begin); 1472 size_t percent_idx = var_name.find('%'); 1473 size_t close_curly_idx = var_name.find('}'); 1474 llvm::StringRef path = var_name; 1475 llvm::StringRef formatter = var_name; 1476 1477 // 'path' will be the dot separated list of objects to transverse up until we hit 1478 // a close curly brace, a percent sign, or an end of string. 1479 if (percent_idx != llvm::StringRef::npos || close_curly_idx != llvm::StringRef::npos) 1480 { 1481 if (percent_idx != llvm::StringRef::npos && close_curly_idx != llvm::StringRef::npos) 1482 { 1483 if (percent_idx < close_curly_idx) 1484 { 1485 path = var_name.slice(0, percent_idx); 1486 formatter = var_name.substr (percent_idx); 1487 } 1488 else 1489 { 1490 path = var_name.slice(0, close_curly_idx); 1491 formatter = var_name.substr (close_curly_idx); 1492 } 1493 } 1494 else if (percent_idx != llvm::StringRef::npos) 1495 { 1496 path = var_name.slice(0, percent_idx); 1497 formatter = var_name.substr (percent_idx); 1498 } 1499 else if (close_curly_idx != llvm::StringRef::npos) 1500 { 1501 path = var_name.slice(0, close_curly_idx); 1502 formatter = var_name.substr (close_curly_idx); 1503 } 1504 } 1505 1506 StructuredData::ObjectSP value = thread_info_dictionary->GetObjectForDotSeparatedPath (path); 1507 1508 if (value.get()) 1509 { 1510 if (value->GetType() == StructuredData::Type::eTypeInteger) 1511 { 1512 if (IsTokenWithFormat (formatter.str().c_str(), "", token_format, "0x%4.4" PRIx64, exe_ctx, sc)) 1513 { 1514 s.Printf(token_format.c_str(), value->GetAsInteger()->GetValue()); 1515 var_success = true; 1516 } 1517 } 1518 else if (value->GetType() == StructuredData::Type::eTypeFloat) 1519 { 1520 s.Printf ("%f", value->GetAsFloat()->GetValue()); 1521 var_success = true; 1522 } 1523 else if (value->GetType() == StructuredData::Type::eTypeString) 1524 { 1525 s.Printf("%s", value->GetAsString()->GetValue().c_str()); 1526 var_success = true; 1527 } 1528 else if (value->GetType() == StructuredData::Type::eTypeArray) 1529 { 1530 if (value->GetAsArray()->GetSize() > 0) 1531 { 1532 s.Printf ("%zu", value->GetAsArray()->GetSize()); 1533 var_success = true; 1534 } 1535 } 1536 else if (value->GetType() == StructuredData::Type::eTypeDictionary) 1537 { 1538 s.Printf ("%zu", value->GetAsDictionary()->GetKeys()->GetAsArray()->GetSize()); 1539 var_success = true; 1540 } 1541 } 1542 1543 return var_success; 1544 } 1545 1546 1547 static bool 1548 FormatPromptRecurse 1549 ( 1550 const char *format, 1551 const SymbolContext *sc, 1552 const ExecutionContext *exe_ctx, 1553 const Address *addr, 1554 Stream &s, 1555 const char **end, 1556 ValueObject* valobj 1557 ) 1558 { 1559 ValueObject* realvalobj = NULL; // makes it super-easy to parse pointers 1560 bool success = true; 1561 const char *p; 1562 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES)); 1563 1564 for (p = format; *p != '\0'; ++p) 1565 { 1566 if (realvalobj) 1567 { 1568 valobj = realvalobj; 1569 realvalobj = NULL; 1570 } 1571 size_t non_special_chars = ::strcspn (p, "${}\\"); 1572 if (non_special_chars > 0) 1573 { 1574 if (success) 1575 s.Write (p, non_special_chars); 1576 p += non_special_chars; 1577 } 1578 1579 if (*p == '\0') 1580 { 1581 break; 1582 } 1583 else if (*p == '{') 1584 { 1585 // Start a new scope that must have everything it needs if it is to 1586 // to make it into the final output stream "s". If you want to make 1587 // a format that only prints out the function or symbol name if there 1588 // is one in the symbol context you can use: 1589 // "{function =${function.name}}" 1590 // The first '{' starts a new scope that end with the matching '}' at 1591 // the end of the string. The contents "function =${function.name}" 1592 // will then be evaluated and only be output if there is a function 1593 // or symbol with a valid name. 1594 StreamString sub_strm; 1595 1596 ++p; // Skip the '{' 1597 1598 if (FormatPromptRecurse (p, sc, exe_ctx, addr, sub_strm, &p, valobj)) 1599 { 1600 // The stream had all it needed 1601 s.Write(sub_strm.GetData(), sub_strm.GetSize()); 1602 } 1603 if (*p != '}') 1604 { 1605 success = false; 1606 break; 1607 } 1608 } 1609 else if (*p == '}') 1610 { 1611 // End of a enclosing scope 1612 break; 1613 } 1614 else if (*p == '$') 1615 { 1616 // We have a prompt variable to print 1617 ++p; 1618 if (*p == '{') 1619 { 1620 ++p; 1621 const char *var_name_begin = p; 1622 const char *var_name_end = ::strchr (p, '}'); 1623 1624 if (var_name_end && var_name_begin < var_name_end) 1625 { 1626 // if we have already failed to parse, skip this variable 1627 if (success) 1628 { 1629 const char *cstr = NULL; 1630 std::string token_format; 1631 Address format_addr; 1632 bool calculate_format_addr_function_offset = false; 1633 // Set reg_kind and reg_num to invalid values 1634 RegisterKind reg_kind = kNumRegisterKinds; 1635 uint32_t reg_num = LLDB_INVALID_REGNUM; 1636 FileSpec format_file_spec; 1637 const RegisterInfo *reg_info = NULL; 1638 RegisterContext *reg_ctx = NULL; 1639 bool do_deref_pointer = false; 1640 ValueObject::ExpressionPathScanEndReason reason_to_stop = ValueObject::eExpressionPathScanEndReasonEndOfString; 1641 ValueObject::ExpressionPathEndResultType final_value_type = ValueObject::eExpressionPathEndResultTypePlain; 1642 1643 // Each variable must set success to true below... 1644 bool var_success = false; 1645 switch (var_name_begin[0]) 1646 { 1647 case '*': 1648 case 'v': 1649 case 's': 1650 { 1651 if (!valobj) 1652 break; 1653 1654 if (log) 1655 log->Printf("[Debugger::FormatPrompt] initial string: %s",var_name_begin); 1656 1657 // check for *var and *svar 1658 if (*var_name_begin == '*') 1659 { 1660 do_deref_pointer = true; 1661 var_name_begin++; 1662 if (log) 1663 log->Printf("[Debugger::FormatPrompt] found a deref, new string is: %s",var_name_begin); 1664 } 1665 1666 if (*var_name_begin == 's') 1667 { 1668 if (!valobj->IsSynthetic()) 1669 valobj = valobj->GetSyntheticValue().get(); 1670 if (!valobj) 1671 break; 1672 var_name_begin++; 1673 if (log) 1674 log->Printf("[Debugger::FormatPrompt] found a synthetic, new string is: %s",var_name_begin); 1675 } 1676 1677 // should be a 'v' by now 1678 if (*var_name_begin != 'v') 1679 break; 1680 1681 if (log) 1682 log->Printf("[Debugger::FormatPrompt] string I am working with: %s",var_name_begin); 1683 1684 ValueObject::ExpressionPathAftermath what_next = (do_deref_pointer ? 1685 ValueObject::eExpressionPathAftermathDereference : ValueObject::eExpressionPathAftermathNothing); 1686 ValueObject::GetValueForExpressionPathOptions options; 1687 options.DontCheckDotVsArrowSyntax().DoAllowBitfieldSyntax().DoAllowFragileIVar().DoAllowSyntheticChildren(); 1688 ValueObject::ValueObjectRepresentationStyle val_obj_display = ValueObject::eValueObjectRepresentationStyleSummary; 1689 ValueObject* target = NULL; 1690 Format custom_format = eFormatInvalid; 1691 const char* var_name_final = NULL; 1692 const char* var_name_final_if_array_range = NULL; 1693 const char* close_bracket_position = NULL; 1694 int64_t index_lower = -1; 1695 int64_t index_higher = -1; 1696 bool is_array_range = false; 1697 const char* first_unparsed; 1698 bool was_plain_var = false; 1699 bool was_var_format = false; 1700 bool was_var_indexed = false; 1701 1702 if (!valobj) break; 1703 // simplest case ${var}, just print valobj's value 1704 if (IsToken (var_name_begin, "var}")) 1705 { 1706 was_plain_var = true; 1707 target = valobj; 1708 val_obj_display = ValueObject::eValueObjectRepresentationStyleValue; 1709 } 1710 else if (IsToken (var_name_begin,"var%")) 1711 { 1712 was_var_format = true; 1713 // this is a variable with some custom format applied to it 1714 const char* percent_position; 1715 target = valobj; 1716 val_obj_display = ValueObject::eValueObjectRepresentationStyleValue; 1717 ScanFormatDescriptor (var_name_begin, 1718 var_name_end, 1719 &var_name_final, 1720 &percent_position, 1721 &custom_format, 1722 &val_obj_display); 1723 } 1724 // this is ${var.something} or multiple .something nested 1725 else if (IsToken (var_name_begin, "var")) 1726 { 1727 if (IsToken (var_name_begin, "var[")) 1728 was_var_indexed = true; 1729 const char* percent_position; 1730 ScanFormatDescriptor (var_name_begin, 1731 var_name_end, 1732 &var_name_final, 1733 &percent_position, 1734 &custom_format, 1735 &val_obj_display); 1736 1737 const char* open_bracket_position; 1738 const char* separator_position; 1739 ScanBracketedRange (var_name_begin, 1740 var_name_end, 1741 var_name_final, 1742 &open_bracket_position, 1743 &separator_position, 1744 &close_bracket_position, 1745 &var_name_final_if_array_range, 1746 &index_lower, 1747 &index_higher); 1748 1749 Error error; 1750 1751 std::string expr_path(var_name_final-var_name_begin-1,0); 1752 memcpy(&expr_path[0], var_name_begin+3,var_name_final-var_name_begin-3); 1753 1754 if (log) 1755 log->Printf("[Debugger::FormatPrompt] symbol to expand: %s",expr_path.c_str()); 1756 1757 target = valobj->GetValueForExpressionPath(expr_path.c_str(), 1758 &first_unparsed, 1759 &reason_to_stop, 1760 &final_value_type, 1761 options, 1762 &what_next).get(); 1763 1764 if (!target) 1765 { 1766 if (log) 1767 log->Printf("[Debugger::FormatPrompt] ERROR: unparsed portion = %s, why stopping = %d," 1768 " final_value_type %d", 1769 first_unparsed, reason_to_stop, final_value_type); 1770 break; 1771 } 1772 else 1773 { 1774 if (log) 1775 log->Printf("[Debugger::FormatPrompt] ALL RIGHT: unparsed portion = %s, why stopping = %d," 1776 " final_value_type %d", 1777 first_unparsed, reason_to_stop, final_value_type); 1778 } 1779 } 1780 else 1781 break; 1782 1783 is_array_range = (final_value_type == ValueObject::eExpressionPathEndResultTypeBoundedRange || 1784 final_value_type == ValueObject::eExpressionPathEndResultTypeUnboundedRange); 1785 1786 do_deref_pointer = (what_next == ValueObject::eExpressionPathAftermathDereference); 1787 1788 if (do_deref_pointer && !is_array_range) 1789 { 1790 // I have not deref-ed yet, let's do it 1791 // this happens when we are not going through GetValueForVariableExpressionPath 1792 // to get to the target ValueObject 1793 Error error; 1794 target = target->Dereference(error).get(); 1795 if (error.Fail()) 1796 { 1797 if (log) 1798 log->Printf("[Debugger::FormatPrompt] ERROR: %s\n", error.AsCString("unknown")); \ 1799 break; 1800 } 1801 do_deref_pointer = false; 1802 } 1803 1804 if (!target) 1805 { 1806 if (log) 1807 log->Printf("[Debugger::FormatPrompt] could not calculate target for prompt expression"); 1808 break; 1809 } 1810 1811 // we do not want to use the summary for a bitfield of type T:n 1812 // if we were originally dealing with just a T - that would get 1813 // us into an endless recursion 1814 if (target->IsBitfield() && was_var_indexed) 1815 { 1816 // TODO: check for a (T:n)-specific summary - we should still obey that 1817 StreamString bitfield_name; 1818 bitfield_name.Printf("%s:%d", target->GetTypeName().AsCString(), target->GetBitfieldBitSize()); 1819 lldb::TypeNameSpecifierImplSP type_sp(new TypeNameSpecifierImpl(bitfield_name.GetData(),false)); 1820 if (!DataVisualization::GetSummaryForType(type_sp)) 1821 val_obj_display = ValueObject::eValueObjectRepresentationStyleValue; 1822 } 1823 1824 // TODO use flags for these 1825 const uint32_t type_info_flags = target->GetClangType().GetTypeInfo(NULL); 1826 bool is_array = (type_info_flags & ClangASTType::eTypeIsArray) != 0; 1827 bool is_pointer = (type_info_flags & ClangASTType::eTypeIsPointer) != 0; 1828 bool is_aggregate = target->GetClangType().IsAggregateType(); 1829 1830 if ((is_array || is_pointer) && (!is_array_range) && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue) // this should be wrong, but there are some exceptions 1831 { 1832 StreamString str_temp; 1833 if (log) 1834 log->Printf("[Debugger::FormatPrompt] I am into array || pointer && !range"); 1835 1836 if (target->HasSpecialPrintableRepresentation(val_obj_display, custom_format)) 1837 { 1838 // try to use the special cases 1839 var_success = target->DumpPrintableRepresentation(str_temp, 1840 val_obj_display, 1841 custom_format); 1842 if (log) 1843 log->Printf("[Debugger::FormatPrompt] special cases did%s match", var_success ? "" : "n't"); 1844 1845 // should not happen 1846 if (var_success) 1847 s << str_temp.GetData(); 1848 var_success = true; 1849 break; 1850 } 1851 else 1852 { 1853 if (was_plain_var) // if ${var} 1854 { 1855 s << target->GetTypeName() << " @ " << target->GetLocationAsCString(); 1856 } 1857 else if (is_pointer) // if pointer, value is the address stored 1858 { 1859 target->DumpPrintableRepresentation (s, 1860 val_obj_display, 1861 custom_format, 1862 ValueObject::ePrintableRepresentationSpecialCasesDisable); 1863 } 1864 var_success = true; 1865 break; 1866 } 1867 } 1868 1869 // if directly trying to print ${var}, and this is an aggregate, display a nice 1870 // type @ location message 1871 if (is_aggregate && was_plain_var) 1872 { 1873 s << target->GetTypeName() << " @ " << target->GetLocationAsCString(); 1874 var_success = true; 1875 break; 1876 } 1877 1878 // if directly trying to print ${var%V}, and this is an aggregate, do not let the user do it 1879 if (is_aggregate && ((was_var_format && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue))) 1880 { 1881 s << "<invalid use of aggregate type>"; 1882 var_success = true; 1883 break; 1884 } 1885 1886 if (!is_array_range) 1887 { 1888 if (log) 1889 log->Printf("[Debugger::FormatPrompt] dumping ordinary printable output"); 1890 var_success = target->DumpPrintableRepresentation(s,val_obj_display, custom_format); 1891 } 1892 else 1893 { 1894 if (log) 1895 log->Printf("[Debugger::FormatPrompt] checking if I can handle as array"); 1896 if (!is_array && !is_pointer) 1897 break; 1898 if (log) 1899 log->Printf("[Debugger::FormatPrompt] handle as array"); 1900 const char* special_directions = NULL; 1901 StreamString special_directions_writer; 1902 if (close_bracket_position && (var_name_end-close_bracket_position > 1)) 1903 { 1904 ConstString additional_data; 1905 additional_data.SetCStringWithLength(close_bracket_position+1, var_name_end-close_bracket_position-1); 1906 special_directions_writer.Printf("${%svar%s}", 1907 do_deref_pointer ? "*" : "", 1908 additional_data.GetCString()); 1909 special_directions = special_directions_writer.GetData(); 1910 } 1911 1912 // let us display items index_lower thru index_higher of this array 1913 s.PutChar('['); 1914 var_success = true; 1915 1916 if (index_higher < 0) 1917 index_higher = valobj->GetNumChildren() - 1; 1918 1919 uint32_t max_num_children = target->GetTargetSP()->GetMaximumNumberOfChildrenToDisplay(); 1920 1921 for (;index_lower<=index_higher;index_lower++) 1922 { 1923 ValueObject* item = ExpandIndexedExpression (target, 1924 index_lower, 1925 exe_ctx->GetFramePtr(), 1926 false).get(); 1927 1928 if (!item) 1929 { 1930 if (log) 1931 log->Printf("[Debugger::FormatPrompt] ERROR in getting child item at index %" PRId64, index_lower); 1932 } 1933 else 1934 { 1935 if (log) 1936 log->Printf("[Debugger::FormatPrompt] special_directions for child item: %s",special_directions); 1937 } 1938 1939 if (!special_directions) 1940 var_success &= item->DumpPrintableRepresentation(s,val_obj_display, custom_format); 1941 else 1942 var_success &= FormatPromptRecurse(special_directions, sc, exe_ctx, addr, s, NULL, item); 1943 1944 if (--max_num_children == 0) 1945 { 1946 s.PutCString(", ..."); 1947 break; 1948 } 1949 1950 if (index_lower < index_higher) 1951 s.PutChar(','); 1952 } 1953 s.PutChar(']'); 1954 } 1955 } 1956 break; 1957 case 'a': 1958 if (IsToken (var_name_begin, "addr}")) 1959 { 1960 if (addr && addr->IsValid()) 1961 { 1962 var_success = true; 1963 format_addr = *addr; 1964 } 1965 } 1966 break; 1967 1968 case 'p': 1969 if (IsToken (var_name_begin, "process.")) 1970 { 1971 if (exe_ctx) 1972 { 1973 Process *process = exe_ctx->GetProcessPtr(); 1974 if (process) 1975 { 1976 var_name_begin += ::strlen ("process."); 1977 if (IsTokenWithFormat (var_name_begin, "id", token_format, "%" PRIu64, exe_ctx, sc)) 1978 { 1979 s.Printf(token_format.c_str(), process->GetID()); 1980 var_success = true; 1981 } 1982 else if ((IsToken (var_name_begin, "name}")) || 1983 (IsToken (var_name_begin, "file.basename}")) || 1984 (IsToken (var_name_begin, "file.fullpath}"))) 1985 { 1986 Module *exe_module = process->GetTarget().GetExecutableModulePointer(); 1987 if (exe_module) 1988 { 1989 if (var_name_begin[0] == 'n' || var_name_begin[5] == 'f') 1990 { 1991 format_file_spec.GetFilename() = exe_module->GetFileSpec().GetFilename(); 1992 var_success = (bool)format_file_spec; 1993 } 1994 else 1995 { 1996 format_file_spec = exe_module->GetFileSpec(); 1997 var_success = (bool)format_file_spec; 1998 } 1999 } 2000 } 2001 else if (IsToken (var_name_begin, "script:")) 2002 { 2003 var_name_begin += ::strlen("script:"); 2004 std::string script_name(var_name_begin,var_name_end); 2005 ScriptInterpreter* script_interpreter = process->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter(); 2006 if (RunScriptFormatKeyword (s, script_interpreter, process, script_name)) 2007 var_success = true; 2008 } 2009 } 2010 } 2011 } 2012 break; 2013 2014 case 't': 2015 if (IsToken (var_name_begin, "thread.")) 2016 { 2017 if (exe_ctx) 2018 { 2019 Thread *thread = exe_ctx->GetThreadPtr(); 2020 if (thread) 2021 { 2022 var_name_begin += ::strlen ("thread."); 2023 if (IsTokenWithFormat (var_name_begin, "id", token_format, "0x%4.4" PRIx64, exe_ctx, sc)) 2024 { 2025 s.Printf(token_format.c_str(), thread->GetID()); 2026 var_success = true; 2027 } 2028 else if (IsTokenWithFormat (var_name_begin, "protocol_id", token_format, "0x%4.4" PRIx64, exe_ctx, sc)) 2029 { 2030 s.Printf(token_format.c_str(), thread->GetProtocolID()); 2031 var_success = true; 2032 } 2033 else if (IsTokenWithFormat (var_name_begin, "index", token_format, "%" PRIu64, exe_ctx, sc)) 2034 { 2035 s.Printf(token_format.c_str(), (uint64_t)thread->GetIndexID()); 2036 var_success = true; 2037 } 2038 else if (IsToken (var_name_begin, "name}")) 2039 { 2040 cstr = thread->GetName(); 2041 var_success = cstr && cstr[0]; 2042 if (var_success) 2043 s.PutCString(cstr); 2044 } 2045 else if (IsToken (var_name_begin, "queue}")) 2046 { 2047 cstr = thread->GetQueueName(); 2048 var_success = cstr && cstr[0]; 2049 if (var_success) 2050 s.PutCString(cstr); 2051 } 2052 else if (IsToken (var_name_begin, "stop-reason}")) 2053 { 2054 StopInfoSP stop_info_sp = thread->GetStopInfo (); 2055 if (stop_info_sp && stop_info_sp->IsValid()) 2056 { 2057 cstr = stop_info_sp->GetDescription(); 2058 if (cstr && cstr[0]) 2059 { 2060 s.PutCString(cstr); 2061 var_success = true; 2062 } 2063 } 2064 } 2065 else if (IsToken (var_name_begin, "return-value}")) 2066 { 2067 StopInfoSP stop_info_sp = thread->GetStopInfo (); 2068 if (stop_info_sp && stop_info_sp->IsValid()) 2069 { 2070 ValueObjectSP return_valobj_sp = StopInfo::GetReturnValueObject (stop_info_sp); 2071 if (return_valobj_sp) 2072 { 2073 return_valobj_sp->Dump(s); 2074 var_success = true; 2075 } 2076 } 2077 } 2078 else if (IsToken (var_name_begin, "script:")) 2079 { 2080 var_name_begin += ::strlen("script:"); 2081 std::string script_name(var_name_begin,var_name_end); 2082 ScriptInterpreter* script_interpreter = thread->GetProcess()->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter(); 2083 if (RunScriptFormatKeyword (s, script_interpreter, thread, script_name)) 2084 var_success = true; 2085 } 2086 else if (IsToken (var_name_begin, "info.")) 2087 { 2088 var_name_begin += ::strlen("info."); 2089 StructuredData::ObjectSP object_sp = thread->GetExtendedInfo(); 2090 if (object_sp && object_sp->GetType() == StructuredData::Type::eTypeDictionary) 2091 { 2092 var_success = FormatThreadExtendedInfoRecurse (var_name_begin, object_sp, sc, exe_ctx, s); 2093 } 2094 } 2095 } 2096 } 2097 } 2098 else if (IsToken (var_name_begin, "target.")) 2099 { 2100 // TODO: hookup properties 2101 // if (!target_properties_sp) 2102 // { 2103 // Target *target = Target::GetTargetFromContexts (exe_ctx, sc); 2104 // if (target) 2105 // target_properties_sp = target->GetProperties(); 2106 // } 2107 // 2108 // if (target_properties_sp) 2109 // { 2110 // var_name_begin += ::strlen ("target."); 2111 // const char *end_property = strchr(var_name_begin, '}'); 2112 // if (end_property) 2113 // { 2114 // ConstString property_name(var_name_begin, end_property - var_name_begin); 2115 // std::string property_value (target_properties_sp->GetPropertyValue(property_name)); 2116 // if (!property_value.empty()) 2117 // { 2118 // s.PutCString (property_value.c_str()); 2119 // var_success = true; 2120 // } 2121 // } 2122 // } 2123 Target *target = Target::GetTargetFromContexts (exe_ctx, sc); 2124 if (target) 2125 { 2126 var_name_begin += ::strlen ("target."); 2127 if (IsToken (var_name_begin, "arch}")) 2128 { 2129 ArchSpec arch (target->GetArchitecture ()); 2130 if (arch.IsValid()) 2131 { 2132 s.PutCString (arch.GetArchitectureName()); 2133 var_success = true; 2134 } 2135 } 2136 else if (IsToken (var_name_begin, "script:")) 2137 { 2138 var_name_begin += ::strlen("script:"); 2139 std::string script_name(var_name_begin,var_name_end); 2140 ScriptInterpreter* script_interpreter = target->GetDebugger().GetCommandInterpreter().GetScriptInterpreter(); 2141 if (RunScriptFormatKeyword (s, script_interpreter, target, script_name)) 2142 var_success = true; 2143 } 2144 } 2145 } 2146 break; 2147 2148 2149 case 'm': 2150 if (IsToken (var_name_begin, "module.")) 2151 { 2152 if (sc && sc->module_sp.get()) 2153 { 2154 Module *module = sc->module_sp.get(); 2155 var_name_begin += ::strlen ("module."); 2156 2157 if (IsToken (var_name_begin, "file.")) 2158 { 2159 if (module->GetFileSpec()) 2160 { 2161 var_name_begin += ::strlen ("file."); 2162 2163 if (IsToken (var_name_begin, "basename}")) 2164 { 2165 format_file_spec.GetFilename() = module->GetFileSpec().GetFilename(); 2166 var_success = (bool)format_file_spec; 2167 } 2168 else if (IsToken (var_name_begin, "fullpath}")) 2169 { 2170 format_file_spec = module->GetFileSpec(); 2171 var_success = (bool)format_file_spec; 2172 } 2173 } 2174 } 2175 } 2176 } 2177 break; 2178 2179 2180 case 'f': 2181 if (IsToken (var_name_begin, "file.")) 2182 { 2183 if (sc && sc->comp_unit != NULL) 2184 { 2185 var_name_begin += ::strlen ("file."); 2186 2187 if (IsToken (var_name_begin, "basename}")) 2188 { 2189 format_file_spec.GetFilename() = sc->comp_unit->GetFilename(); 2190 var_success = (bool)format_file_spec; 2191 } 2192 else if (IsToken (var_name_begin, "fullpath}")) 2193 { 2194 format_file_spec = *sc->comp_unit; 2195 var_success = (bool)format_file_spec; 2196 } 2197 } 2198 } 2199 else if (IsToken (var_name_begin, "frame.")) 2200 { 2201 if (exe_ctx) 2202 { 2203 StackFrame *frame = exe_ctx->GetFramePtr(); 2204 if (frame) 2205 { 2206 var_name_begin += ::strlen ("frame."); 2207 if (IsToken (var_name_begin, "index}")) 2208 { 2209 s.Printf("%u", frame->GetFrameIndex()); 2210 var_success = true; 2211 } 2212 else if (IsToken (var_name_begin, "pc}")) 2213 { 2214 reg_kind = eRegisterKindGeneric; 2215 reg_num = LLDB_REGNUM_GENERIC_PC; 2216 var_success = true; 2217 } 2218 else if (IsToken (var_name_begin, "sp}")) 2219 { 2220 reg_kind = eRegisterKindGeneric; 2221 reg_num = LLDB_REGNUM_GENERIC_SP; 2222 var_success = true; 2223 } 2224 else if (IsToken (var_name_begin, "fp}")) 2225 { 2226 reg_kind = eRegisterKindGeneric; 2227 reg_num = LLDB_REGNUM_GENERIC_FP; 2228 var_success = true; 2229 } 2230 else if (IsToken (var_name_begin, "flags}")) 2231 { 2232 reg_kind = eRegisterKindGeneric; 2233 reg_num = LLDB_REGNUM_GENERIC_FLAGS; 2234 var_success = true; 2235 } 2236 else if (IsToken (var_name_begin, "reg.")) 2237 { 2238 reg_ctx = frame->GetRegisterContext().get(); 2239 if (reg_ctx) 2240 { 2241 var_name_begin += ::strlen ("reg."); 2242 if (var_name_begin < var_name_end) 2243 { 2244 std::string reg_name (var_name_begin, var_name_end); 2245 reg_info = reg_ctx->GetRegisterInfoByName (reg_name.c_str()); 2246 if (reg_info) 2247 var_success = true; 2248 } 2249 } 2250 } 2251 else if (IsToken (var_name_begin, "script:")) 2252 { 2253 var_name_begin += ::strlen("script:"); 2254 std::string script_name(var_name_begin,var_name_end); 2255 ScriptInterpreter* script_interpreter = frame->GetThread()->GetProcess()->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter(); 2256 if (RunScriptFormatKeyword (s, script_interpreter, frame, script_name)) 2257 var_success = true; 2258 } 2259 } 2260 } 2261 } 2262 else if (IsToken (var_name_begin, "function.")) 2263 { 2264 if (sc && (sc->function != NULL || sc->symbol != NULL)) 2265 { 2266 var_name_begin += ::strlen ("function."); 2267 if (IsToken (var_name_begin, "id}")) 2268 { 2269 if (sc->function) 2270 s.Printf("function{0x%8.8" PRIx64 "}", sc->function->GetID()); 2271 else 2272 s.Printf("symbol[%u]", sc->symbol->GetID()); 2273 2274 var_success = true; 2275 } 2276 else if (IsToken (var_name_begin, "name}")) 2277 { 2278 if (sc->function) 2279 cstr = sc->function->GetName().AsCString (NULL); 2280 else if (sc->symbol) 2281 cstr = sc->symbol->GetName().AsCString (NULL); 2282 if (cstr) 2283 { 2284 s.PutCString(cstr); 2285 2286 if (sc->block) 2287 { 2288 Block *inline_block = sc->block->GetContainingInlinedBlock (); 2289 if (inline_block) 2290 { 2291 const InlineFunctionInfo *inline_info = sc->block->GetInlinedFunctionInfo(); 2292 if (inline_info) 2293 { 2294 s.PutCString(" [inlined] "); 2295 inline_info->GetName().Dump(&s); 2296 } 2297 } 2298 } 2299 var_success = true; 2300 } 2301 } 2302 else if (IsToken (var_name_begin, "name-with-args}")) 2303 { 2304 // Print the function name with arguments in it 2305 2306 if (sc->function) 2307 { 2308 var_success = true; 2309 ExecutionContextScope *exe_scope = exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL; 2310 cstr = sc->function->GetName().AsCString (NULL); 2311 if (cstr) 2312 { 2313 const InlineFunctionInfo *inline_info = NULL; 2314 VariableListSP variable_list_sp; 2315 bool get_function_vars = true; 2316 if (sc->block) 2317 { 2318 Block *inline_block = sc->block->GetContainingInlinedBlock (); 2319 2320 if (inline_block) 2321 { 2322 get_function_vars = false; 2323 inline_info = sc->block->GetInlinedFunctionInfo(); 2324 if (inline_info) 2325 variable_list_sp = inline_block->GetBlockVariableList (true); 2326 } 2327 } 2328 2329 if (get_function_vars) 2330 { 2331 variable_list_sp = sc->function->GetBlock(true).GetBlockVariableList (true); 2332 } 2333 2334 if (inline_info) 2335 { 2336 s.PutCString (cstr); 2337 s.PutCString (" [inlined] "); 2338 cstr = inline_info->GetName().GetCString(); 2339 } 2340 2341 VariableList args; 2342 if (variable_list_sp) 2343 variable_list_sp->AppendVariablesWithScope(eValueTypeVariableArgument, args); 2344 if (args.GetSize() > 0) 2345 { 2346 const char *open_paren = strchr (cstr, '('); 2347 const char *close_paren = NULL; 2348 if (open_paren) 2349 { 2350 if (IsToken (open_paren, "(anonymous namespace)")) 2351 { 2352 open_paren = strchr (open_paren + strlen("(anonymous namespace)"), '('); 2353 if (open_paren) 2354 close_paren = strchr (open_paren, ')'); 2355 } 2356 else 2357 close_paren = strchr (open_paren, ')'); 2358 } 2359 2360 if (open_paren) 2361 s.Write(cstr, open_paren - cstr + 1); 2362 else 2363 { 2364 s.PutCString (cstr); 2365 s.PutChar ('('); 2366 } 2367 const size_t num_args = args.GetSize(); 2368 for (size_t arg_idx = 0; arg_idx < num_args; ++arg_idx) 2369 { 2370 std::string buffer; 2371 2372 VariableSP var_sp (args.GetVariableAtIndex (arg_idx)); 2373 ValueObjectSP var_value_sp (ValueObjectVariable::Create (exe_scope, var_sp)); 2374 const char *var_representation = nullptr; 2375 const char *var_name = var_value_sp->GetName().GetCString(); 2376 if (var_value_sp->GetClangType().IsAggregateType() && 2377 DataVisualization::ShouldPrintAsOneLiner(*var_value_sp.get())) 2378 { 2379 static StringSummaryFormat format(TypeSummaryImpl::Flags() 2380 .SetHideItemNames(false) 2381 .SetShowMembersOneLiner(true), 2382 ""); 2383 format.FormatObject(var_value_sp.get(), buffer); 2384 var_representation = buffer.c_str(); 2385 } 2386 else 2387 var_representation = var_value_sp->GetValueAsCString(); 2388 if (arg_idx > 0) 2389 s.PutCString (", "); 2390 if (var_value_sp->GetError().Success()) 2391 { 2392 if (var_representation) 2393 s.Printf ("%s=%s", var_name, var_representation); 2394 else 2395 s.Printf ("%s=%s at %s", var_name, var_value_sp->GetTypeName().GetCString(), var_value_sp->GetLocationAsCString()); 2396 } 2397 else 2398 s.Printf ("%s=<unavailable>", var_name); 2399 } 2400 2401 if (close_paren) 2402 s.PutCString (close_paren); 2403 else 2404 s.PutChar(')'); 2405 2406 } 2407 else 2408 { 2409 s.PutCString(cstr); 2410 } 2411 } 2412 } 2413 else if (sc->symbol) 2414 { 2415 cstr = sc->symbol->GetName().AsCString (NULL); 2416 if (cstr) 2417 { 2418 s.PutCString(cstr); 2419 var_success = true; 2420 } 2421 } 2422 } 2423 else if (IsToken (var_name_begin, "addr-offset}")) 2424 { 2425 var_success = addr != NULL; 2426 if (var_success) 2427 { 2428 format_addr = *addr; 2429 calculate_format_addr_function_offset = true; 2430 } 2431 } 2432 else if (IsToken (var_name_begin, "line-offset}")) 2433 { 2434 var_success = sc->line_entry.range.GetBaseAddress().IsValid(); 2435 if (var_success) 2436 { 2437 format_addr = sc->line_entry.range.GetBaseAddress(); 2438 calculate_format_addr_function_offset = true; 2439 } 2440 } 2441 else if (IsToken (var_name_begin, "pc-offset}")) 2442 { 2443 StackFrame *frame = exe_ctx->GetFramePtr(); 2444 var_success = frame != NULL; 2445 if (var_success) 2446 { 2447 format_addr = frame->GetFrameCodeAddress(); 2448 calculate_format_addr_function_offset = true; 2449 } 2450 } 2451 } 2452 } 2453 break; 2454 2455 case 'l': 2456 if (IsToken (var_name_begin, "line.")) 2457 { 2458 if (sc && sc->line_entry.IsValid()) 2459 { 2460 var_name_begin += ::strlen ("line."); 2461 if (IsToken (var_name_begin, "file.")) 2462 { 2463 var_name_begin += ::strlen ("file."); 2464 2465 if (IsToken (var_name_begin, "basename}")) 2466 { 2467 format_file_spec.GetFilename() = sc->line_entry.file.GetFilename(); 2468 var_success = (bool)format_file_spec; 2469 } 2470 else if (IsToken (var_name_begin, "fullpath}")) 2471 { 2472 format_file_spec = sc->line_entry.file; 2473 var_success = (bool)format_file_spec; 2474 } 2475 } 2476 else if (IsTokenWithFormat (var_name_begin, "number", token_format, "%" PRIu64, exe_ctx, sc)) 2477 { 2478 var_success = true; 2479 s.Printf(token_format.c_str(), (uint64_t)sc->line_entry.line); 2480 } 2481 else if ((IsToken (var_name_begin, "start-addr}")) || 2482 (IsToken (var_name_begin, "end-addr}"))) 2483 { 2484 var_success = sc && sc->line_entry.range.GetBaseAddress().IsValid(); 2485 if (var_success) 2486 { 2487 format_addr = sc->line_entry.range.GetBaseAddress(); 2488 if (var_name_begin[0] == 'e') 2489 format_addr.Slide (sc->line_entry.range.GetByteSize()); 2490 } 2491 } 2492 } 2493 } 2494 break; 2495 } 2496 2497 if (var_success) 2498 { 2499 // If format addr is valid, then we need to print an address 2500 if (reg_num != LLDB_INVALID_REGNUM) 2501 { 2502 StackFrame *frame = exe_ctx->GetFramePtr(); 2503 // We have a register value to display... 2504 if (reg_num == LLDB_REGNUM_GENERIC_PC && reg_kind == eRegisterKindGeneric) 2505 { 2506 format_addr = frame->GetFrameCodeAddress(); 2507 } 2508 else 2509 { 2510 if (reg_ctx == NULL) 2511 reg_ctx = frame->GetRegisterContext().get(); 2512 2513 if (reg_ctx) 2514 { 2515 if (reg_kind != kNumRegisterKinds) 2516 reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(reg_kind, reg_num); 2517 reg_info = reg_ctx->GetRegisterInfoAtIndex (reg_num); 2518 var_success = reg_info != NULL; 2519 } 2520 } 2521 } 2522 2523 if (reg_info != NULL) 2524 { 2525 RegisterValue reg_value; 2526 var_success = reg_ctx->ReadRegister (reg_info, reg_value); 2527 if (var_success) 2528 { 2529 reg_value.Dump(&s, reg_info, false, false, eFormatDefault); 2530 } 2531 } 2532 2533 if (format_file_spec) 2534 { 2535 s << format_file_spec; 2536 } 2537 2538 // If format addr is valid, then we need to print an address 2539 if (format_addr.IsValid()) 2540 { 2541 var_success = false; 2542 2543 if (calculate_format_addr_function_offset) 2544 { 2545 Address func_addr; 2546 2547 if (sc) 2548 { 2549 if (sc->function) 2550 { 2551 func_addr = sc->function->GetAddressRange().GetBaseAddress(); 2552 if (sc->block) 2553 { 2554 // Check to make sure we aren't in an inline 2555 // function. If we are, use the inline block 2556 // range that contains "format_addr" since 2557 // blocks can be discontiguous. 2558 Block *inline_block = sc->block->GetContainingInlinedBlock (); 2559 AddressRange inline_range; 2560 if (inline_block && inline_block->GetRangeContainingAddress (format_addr, inline_range)) 2561 func_addr = inline_range.GetBaseAddress(); 2562 } 2563 } 2564 else if (sc->symbol && sc->symbol->ValueIsAddress()) 2565 func_addr = sc->symbol->GetAddress(); 2566 } 2567 2568 if (func_addr.IsValid()) 2569 { 2570 if (func_addr.GetSection() == format_addr.GetSection()) 2571 { 2572 addr_t func_file_addr = func_addr.GetFileAddress(); 2573 addr_t addr_file_addr = format_addr.GetFileAddress(); 2574 if (addr_file_addr > func_file_addr) 2575 s.Printf(" + %" PRIu64, addr_file_addr - func_file_addr); 2576 else if (addr_file_addr < func_file_addr) 2577 s.Printf(" - %" PRIu64, func_file_addr - addr_file_addr); 2578 var_success = true; 2579 } 2580 else 2581 { 2582 Target *target = Target::GetTargetFromContexts (exe_ctx, sc); 2583 if (target) 2584 { 2585 addr_t func_load_addr = func_addr.GetLoadAddress (target); 2586 addr_t addr_load_addr = format_addr.GetLoadAddress (target); 2587 if (addr_load_addr > func_load_addr) 2588 s.Printf(" + %" PRIu64, addr_load_addr - func_load_addr); 2589 else if (addr_load_addr < func_load_addr) 2590 s.Printf(" - %" PRIu64, func_load_addr - addr_load_addr); 2591 var_success = true; 2592 } 2593 } 2594 } 2595 } 2596 else 2597 { 2598 Target *target = Target::GetTargetFromContexts (exe_ctx, sc); 2599 addr_t vaddr = LLDB_INVALID_ADDRESS; 2600 if (exe_ctx && !target->GetSectionLoadList().IsEmpty()) 2601 vaddr = format_addr.GetLoadAddress (target); 2602 if (vaddr == LLDB_INVALID_ADDRESS) 2603 vaddr = format_addr.GetFileAddress (); 2604 2605 if (vaddr != LLDB_INVALID_ADDRESS) 2606 { 2607 int addr_width = target->GetArchitecture().GetAddressByteSize() * 2; 2608 if (addr_width == 0) 2609 addr_width = 16; 2610 s.Printf("0x%*.*" PRIx64, addr_width, addr_width, vaddr); 2611 var_success = true; 2612 } 2613 } 2614 } 2615 } 2616 2617 if (var_success == false) 2618 success = false; 2619 } 2620 p = var_name_end; 2621 } 2622 else 2623 break; 2624 } 2625 else 2626 { 2627 // We got a dollar sign with no '{' after it, it must just be a dollar sign 2628 s.PutChar(*p); 2629 } 2630 } 2631 else if (*p == '\\') 2632 { 2633 ++p; // skip the slash 2634 switch (*p) 2635 { 2636 case 'a': s.PutChar ('\a'); break; 2637 case 'b': s.PutChar ('\b'); break; 2638 case 'f': s.PutChar ('\f'); break; 2639 case 'n': s.PutChar ('\n'); break; 2640 case 'r': s.PutChar ('\r'); break; 2641 case 't': s.PutChar ('\t'); break; 2642 case 'v': s.PutChar ('\v'); break; 2643 case '\'': s.PutChar ('\''); break; 2644 case '\\': s.PutChar ('\\'); break; 2645 case '0': 2646 // 1 to 3 octal chars 2647 { 2648 // Make a string that can hold onto the initial zero char, 2649 // up to 3 octal digits, and a terminating NULL. 2650 char oct_str[5] = { 0, 0, 0, 0, 0 }; 2651 2652 int i; 2653 for (i=0; (p[i] >= '0' && p[i] <= '7') && i<4; ++i) 2654 oct_str[i] = p[i]; 2655 2656 // We don't want to consume the last octal character since 2657 // the main for loop will do this for us, so we advance p by 2658 // one less than i (even if i is zero) 2659 p += i - 1; 2660 unsigned long octal_value = ::strtoul (oct_str, NULL, 8); 2661 if (octal_value <= UINT8_MAX) 2662 { 2663 s.PutChar((char)octal_value); 2664 } 2665 } 2666 break; 2667 2668 case 'x': 2669 // hex number in the format 2670 if (isxdigit(p[1])) 2671 { 2672 ++p; // Skip the 'x' 2673 2674 // Make a string that can hold onto two hex chars plus a 2675 // NULL terminator 2676 char hex_str[3] = { 0,0,0 }; 2677 hex_str[0] = *p; 2678 if (isxdigit(p[1])) 2679 { 2680 ++p; // Skip the first of the two hex chars 2681 hex_str[1] = *p; 2682 } 2683 2684 unsigned long hex_value = strtoul (hex_str, NULL, 16); 2685 if (hex_value <= UINT8_MAX) 2686 s.PutChar ((char)hex_value); 2687 } 2688 else 2689 { 2690 s.PutChar('x'); 2691 } 2692 break; 2693 2694 default: 2695 // Just desensitize any other character by just printing what 2696 // came after the '\' 2697 s << *p; 2698 break; 2699 2700 } 2701 2702 } 2703 } 2704 if (end) 2705 *end = p; 2706 return success; 2707 } 2708 2709 bool 2710 Debugger::FormatPrompt 2711 ( 2712 const char *format, 2713 const SymbolContext *sc, 2714 const ExecutionContext *exe_ctx, 2715 const Address *addr, 2716 Stream &s, 2717 ValueObject* valobj 2718 ) 2719 { 2720 bool use_color = exe_ctx ? exe_ctx->GetTargetRef().GetDebugger().GetUseColor() : true; 2721 std::string format_str = lldb_utility::ansi::FormatAnsiTerminalCodes (format, use_color); 2722 if (format_str.length()) 2723 format = format_str.c_str(); 2724 return FormatPromptRecurse (format, sc, exe_ctx, addr, s, NULL, valobj); 2725 } 2726 2727 void 2728 Debugger::SetLoggingCallback (lldb::LogOutputCallback log_callback, void *baton) 2729 { 2730 // For simplicity's sake, I am not going to deal with how to close down any 2731 // open logging streams, I just redirect everything from here on out to the 2732 // callback. 2733 m_log_callback_stream_sp.reset (new StreamCallback (log_callback, baton)); 2734 } 2735 2736 bool 2737 Debugger::EnableLog (const char *channel, const char **categories, const char *log_file, uint32_t log_options, Stream &error_stream) 2738 { 2739 Log::Callbacks log_callbacks; 2740 2741 StreamSP log_stream_sp; 2742 if (m_log_callback_stream_sp) 2743 { 2744 log_stream_sp = m_log_callback_stream_sp; 2745 // For now when using the callback mode you always get thread & timestamp. 2746 log_options |= LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_THREAD_NAME; 2747 } 2748 else if (log_file == NULL || *log_file == '\0') 2749 { 2750 log_stream_sp = GetOutputFile(); 2751 } 2752 else 2753 { 2754 LogStreamMap::iterator pos = m_log_streams.find(log_file); 2755 if (pos != m_log_streams.end()) 2756 log_stream_sp = pos->second.lock(); 2757 if (!log_stream_sp) 2758 { 2759 log_stream_sp.reset (new StreamFile (log_file)); 2760 m_log_streams[log_file] = log_stream_sp; 2761 } 2762 } 2763 assert (log_stream_sp.get()); 2764 2765 if (log_options == 0) 2766 log_options = LLDB_LOG_OPTION_PREPEND_THREAD_NAME | LLDB_LOG_OPTION_THREADSAFE; 2767 2768 if (Log::GetLogChannelCallbacks (ConstString(channel), log_callbacks)) 2769 { 2770 log_callbacks.enable (log_stream_sp, log_options, categories, &error_stream); 2771 return true; 2772 } 2773 else 2774 { 2775 LogChannelSP log_channel_sp (LogChannel::FindPlugin (channel)); 2776 if (log_channel_sp) 2777 { 2778 if (log_channel_sp->Enable (log_stream_sp, log_options, &error_stream, categories)) 2779 { 2780 return true; 2781 } 2782 else 2783 { 2784 error_stream.Printf ("Invalid log channel '%s'.\n", channel); 2785 return false; 2786 } 2787 } 2788 else 2789 { 2790 error_stream.Printf ("Invalid log channel '%s'.\n", channel); 2791 return false; 2792 } 2793 } 2794 return false; 2795 } 2796 2797 SourceManager & 2798 Debugger::GetSourceManager () 2799 { 2800 if (m_source_manager_ap.get() == NULL) 2801 m_source_manager_ap.reset (new SourceManager (shared_from_this())); 2802 return *m_source_manager_ap; 2803 } 2804 2805 2806 2807 // This function handles events that were broadcast by the process. 2808 void 2809 Debugger::HandleBreakpointEvent (const EventSP &event_sp) 2810 { 2811 using namespace lldb; 2812 const uint32_t event_type = Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent (event_sp); 2813 2814 // if (event_type & eBreakpointEventTypeAdded 2815 // || event_type & eBreakpointEventTypeRemoved 2816 // || event_type & eBreakpointEventTypeEnabled 2817 // || event_type & eBreakpointEventTypeDisabled 2818 // || event_type & eBreakpointEventTypeCommandChanged 2819 // || event_type & eBreakpointEventTypeConditionChanged 2820 // || event_type & eBreakpointEventTypeIgnoreChanged 2821 // || event_type & eBreakpointEventTypeLocationsResolved) 2822 // { 2823 // // Don't do anything about these events, since the breakpoint commands already echo these actions. 2824 // } 2825 // 2826 if (event_type & eBreakpointEventTypeLocationsAdded) 2827 { 2828 uint32_t num_new_locations = Breakpoint::BreakpointEventData::GetNumBreakpointLocationsFromEvent(event_sp); 2829 if (num_new_locations > 0) 2830 { 2831 BreakpointSP breakpoint = Breakpoint::BreakpointEventData::GetBreakpointFromEvent(event_sp); 2832 StreamFileSP output_sp (GetOutputFile()); 2833 if (output_sp) 2834 { 2835 output_sp->Printf("%d location%s added to breakpoint %d\n", 2836 num_new_locations, 2837 num_new_locations == 1 ? "" : "s", 2838 breakpoint->GetID()); 2839 RefreshTopIOHandler(); 2840 } 2841 } 2842 } 2843 // else if (event_type & eBreakpointEventTypeLocationsRemoved) 2844 // { 2845 // // These locations just get disabled, not sure it is worth spamming folks about this on the command line. 2846 // } 2847 // else if (event_type & eBreakpointEventTypeLocationsResolved) 2848 // { 2849 // // This might be an interesting thing to note, but I'm going to leave it quiet for now, it just looked noisy. 2850 // } 2851 } 2852 2853 size_t 2854 Debugger::GetProcessSTDOUT (Process *process, Stream *stream) 2855 { 2856 size_t total_bytes = 0; 2857 if (stream == NULL) 2858 stream = GetOutputFile().get(); 2859 2860 if (stream) 2861 { 2862 // The process has stuff waiting for stdout; get it and write it out to the appropriate place. 2863 if (process == NULL) 2864 { 2865 TargetSP target_sp = GetTargetList().GetSelectedTarget(); 2866 if (target_sp) 2867 process = target_sp->GetProcessSP().get(); 2868 } 2869 if (process) 2870 { 2871 Error error; 2872 size_t len; 2873 char stdio_buffer[1024]; 2874 while ((len = process->GetSTDOUT (stdio_buffer, sizeof (stdio_buffer), error)) > 0) 2875 { 2876 stream->Write(stdio_buffer, len); 2877 total_bytes += len; 2878 } 2879 } 2880 stream->Flush(); 2881 } 2882 return total_bytes; 2883 } 2884 2885 size_t 2886 Debugger::GetProcessSTDERR (Process *process, Stream *stream) 2887 { 2888 size_t total_bytes = 0; 2889 if (stream == NULL) 2890 stream = GetOutputFile().get(); 2891 2892 if (stream) 2893 { 2894 // The process has stuff waiting for stderr; get it and write it out to the appropriate place. 2895 if (process == NULL) 2896 { 2897 TargetSP target_sp = GetTargetList().GetSelectedTarget(); 2898 if (target_sp) 2899 process = target_sp->GetProcessSP().get(); 2900 } 2901 if (process) 2902 { 2903 Error error; 2904 size_t len; 2905 char stdio_buffer[1024]; 2906 while ((len = process->GetSTDERR (stdio_buffer, sizeof (stdio_buffer), error)) > 0) 2907 { 2908 stream->Write(stdio_buffer, len); 2909 total_bytes += len; 2910 } 2911 } 2912 stream->Flush(); 2913 } 2914 return total_bytes; 2915 } 2916 2917 // This function handles events that were broadcast by the process. 2918 void 2919 Debugger::HandleProcessEvent (const EventSP &event_sp) 2920 { 2921 using namespace lldb; 2922 const uint32_t event_type = event_sp->GetType(); 2923 ProcessSP process_sp = Process::ProcessEventData::GetProcessFromEvent(event_sp.get()); 2924 2925 StreamString output_stream; 2926 StreamString error_stream; 2927 const bool gui_enabled = IsForwardingEvents(); 2928 2929 if (!gui_enabled) 2930 { 2931 bool pop_process_io_handler = false; 2932 assert (process_sp); 2933 2934 if (event_type & Process::eBroadcastBitSTDOUT || event_type & Process::eBroadcastBitStateChanged) 2935 { 2936 GetProcessSTDOUT (process_sp.get(), &output_stream); 2937 } 2938 2939 if (event_type & Process::eBroadcastBitSTDERR || event_type & Process::eBroadcastBitStateChanged) 2940 { 2941 GetProcessSTDERR (process_sp.get(), &error_stream); 2942 } 2943 2944 if (event_type & Process::eBroadcastBitStateChanged) 2945 { 2946 2947 // Drain all stout and stderr so we don't see any output come after 2948 // we print our prompts 2949 // Something changed in the process; get the event and report the process's current status and location to 2950 // the user. 2951 StateType event_state = Process::ProcessEventData::GetStateFromEvent (event_sp.get()); 2952 if (event_state == eStateInvalid) 2953 return; 2954 2955 switch (event_state) 2956 { 2957 case eStateInvalid: 2958 case eStateUnloaded: 2959 case eStateConnected: 2960 case eStateAttaching: 2961 case eStateLaunching: 2962 case eStateStepping: 2963 case eStateDetached: 2964 { 2965 output_stream.Printf("Process %" PRIu64 " %s\n", 2966 process_sp->GetID(), 2967 StateAsCString (event_state)); 2968 2969 if (event_state == eStateDetached) 2970 pop_process_io_handler = true; 2971 } 2972 break; 2973 2974 case eStateRunning: 2975 // Don't be chatty when we run... 2976 break; 2977 2978 case eStateExited: 2979 process_sp->GetStatus(output_stream); 2980 pop_process_io_handler = true; 2981 break; 2982 2983 case eStateStopped: 2984 case eStateCrashed: 2985 case eStateSuspended: 2986 // Make sure the program hasn't been auto-restarted: 2987 if (Process::ProcessEventData::GetRestartedFromEvent (event_sp.get())) 2988 { 2989 size_t num_reasons = Process::ProcessEventData::GetNumRestartedReasons(event_sp.get()); 2990 if (num_reasons > 0) 2991 { 2992 // FIXME: Do we want to report this, or would that just be annoyingly chatty? 2993 if (num_reasons == 1) 2994 { 2995 const char *reason = Process::ProcessEventData::GetRestartedReasonAtIndex (event_sp.get(), 0); 2996 output_stream.Printf("Process %" PRIu64 " stopped and restarted: %s\n", 2997 process_sp->GetID(), 2998 reason ? reason : "<UNKNOWN REASON>"); 2999 } 3000 else 3001 { 3002 output_stream.Printf("Process %" PRIu64 " stopped and restarted, reasons:\n", 3003 process_sp->GetID()); 3004 3005 3006 for (size_t i = 0; i < num_reasons; i++) 3007 { 3008 const char *reason = Process::ProcessEventData::GetRestartedReasonAtIndex (event_sp.get(), i); 3009 output_stream.Printf("\t%s\n", reason ? reason : "<UNKNOWN REASON>"); 3010 } 3011 } 3012 } 3013 } 3014 else 3015 { 3016 // Lock the thread list so it doesn't change on us, this is the scope for the locker: 3017 { 3018 ThreadList &thread_list = process_sp->GetThreadList(); 3019 Mutex::Locker locker (thread_list.GetMutex()); 3020 3021 ThreadSP curr_thread (thread_list.GetSelectedThread()); 3022 ThreadSP thread; 3023 StopReason curr_thread_stop_reason = eStopReasonInvalid; 3024 if (curr_thread) 3025 curr_thread_stop_reason = curr_thread->GetStopReason(); 3026 if (!curr_thread || 3027 !curr_thread->IsValid() || 3028 curr_thread_stop_reason == eStopReasonInvalid || 3029 curr_thread_stop_reason == eStopReasonNone) 3030 { 3031 // Prefer a thread that has just completed its plan over another thread as current thread. 3032 ThreadSP plan_thread; 3033 ThreadSP other_thread; 3034 const size_t num_threads = thread_list.GetSize(); 3035 size_t i; 3036 for (i = 0; i < num_threads; ++i) 3037 { 3038 thread = thread_list.GetThreadAtIndex(i); 3039 StopReason thread_stop_reason = thread->GetStopReason(); 3040 switch (thread_stop_reason) 3041 { 3042 case eStopReasonInvalid: 3043 case eStopReasonNone: 3044 break; 3045 3046 case eStopReasonTrace: 3047 case eStopReasonBreakpoint: 3048 case eStopReasonWatchpoint: 3049 case eStopReasonSignal: 3050 case eStopReasonException: 3051 case eStopReasonExec: 3052 case eStopReasonThreadExiting: 3053 if (!other_thread) 3054 other_thread = thread; 3055 break; 3056 case eStopReasonPlanComplete: 3057 if (!plan_thread) 3058 plan_thread = thread; 3059 break; 3060 } 3061 } 3062 if (plan_thread) 3063 thread_list.SetSelectedThreadByID (plan_thread->GetID()); 3064 else if (other_thread) 3065 thread_list.SetSelectedThreadByID (other_thread->GetID()); 3066 else 3067 { 3068 if (curr_thread && curr_thread->IsValid()) 3069 thread = curr_thread; 3070 else 3071 thread = thread_list.GetThreadAtIndex(0); 3072 3073 if (thread) 3074 thread_list.SetSelectedThreadByID (thread->GetID()); 3075 } 3076 } 3077 } 3078 // Drop the ThreadList mutex by here, since GetThreadStatus below might have to run code, 3079 // e.g. for Data formatters, and if we hold the ThreadList mutex, then the process is going to 3080 // have a hard time restarting the process. 3081 3082 if (GetTargetList().GetSelectedTarget().get() == &process_sp->GetTarget()) 3083 { 3084 const bool only_threads_with_stop_reason = true; 3085 const uint32_t start_frame = 0; 3086 const uint32_t num_frames = 1; 3087 const uint32_t num_frames_with_source = 1; 3088 process_sp->GetStatus(output_stream); 3089 process_sp->GetThreadStatus (output_stream, 3090 only_threads_with_stop_reason, 3091 start_frame, 3092 num_frames, 3093 num_frames_with_source); 3094 } 3095 else 3096 { 3097 uint32_t target_idx = GetTargetList().GetIndexOfTarget(process_sp->GetTarget().shared_from_this()); 3098 if (target_idx != UINT32_MAX) 3099 output_stream.Printf ("Target %d: (", target_idx); 3100 else 3101 output_stream.Printf ("Target <unknown index>: ("); 3102 process_sp->GetTarget().Dump (&output_stream, eDescriptionLevelBrief); 3103 output_stream.Printf (") stopped.\n"); 3104 } 3105 3106 // Pop the process IO handler 3107 pop_process_io_handler = true; 3108 } 3109 break; 3110 } 3111 } 3112 3113 if (output_stream.GetSize() || error_stream.GetSize()) 3114 { 3115 StreamFileSP error_stream_sp (GetOutputFile()); 3116 bool top_io_handler_hid = false; 3117 3118 if (process_sp->ProcessIOHandlerIsActive() == false) 3119 top_io_handler_hid = HideTopIOHandler(); 3120 3121 if (output_stream.GetSize()) 3122 { 3123 StreamFileSP output_stream_sp (GetOutputFile()); 3124 if (output_stream_sp) 3125 output_stream_sp->Write (output_stream.GetData(), output_stream.GetSize()); 3126 } 3127 3128 if (error_stream.GetSize()) 3129 { 3130 StreamFileSP error_stream_sp (GetErrorFile()); 3131 if (error_stream_sp) 3132 error_stream_sp->Write (error_stream.GetData(), error_stream.GetSize()); 3133 } 3134 3135 if (top_io_handler_hid) 3136 RefreshTopIOHandler(); 3137 } 3138 3139 if (pop_process_io_handler) 3140 process_sp->PopProcessIOHandler(); 3141 } 3142 } 3143 3144 void 3145 Debugger::HandleThreadEvent (const EventSP &event_sp) 3146 { 3147 // At present the only thread event we handle is the Frame Changed event, 3148 // and all we do for that is just reprint the thread status for that thread. 3149 using namespace lldb; 3150 const uint32_t event_type = event_sp->GetType(); 3151 if (event_type == Thread::eBroadcastBitStackChanged || 3152 event_type == Thread::eBroadcastBitThreadSelected ) 3153 { 3154 ThreadSP thread_sp (Thread::ThreadEventData::GetThreadFromEvent (event_sp.get())); 3155 if (thread_sp) 3156 { 3157 HideTopIOHandler(); 3158 StreamFileSP stream_sp (GetOutputFile()); 3159 thread_sp->GetStatus(*stream_sp, 0, 1, 1); 3160 RefreshTopIOHandler(); 3161 } 3162 } 3163 } 3164 3165 bool 3166 Debugger::IsForwardingEvents () 3167 { 3168 return (bool)m_forward_listener_sp; 3169 } 3170 3171 void 3172 Debugger::EnableForwardEvents (const ListenerSP &listener_sp) 3173 { 3174 m_forward_listener_sp = listener_sp; 3175 } 3176 3177 void 3178 Debugger::CancelForwardEvents (const ListenerSP &listener_sp) 3179 { 3180 m_forward_listener_sp.reset(); 3181 } 3182 3183 3184 void 3185 Debugger::DefaultEventHandler() 3186 { 3187 Listener& listener(GetListener()); 3188 ConstString broadcaster_class_target(Target::GetStaticBroadcasterClass()); 3189 ConstString broadcaster_class_process(Process::GetStaticBroadcasterClass()); 3190 ConstString broadcaster_class_thread(Thread::GetStaticBroadcasterClass()); 3191 BroadcastEventSpec target_event_spec (broadcaster_class_target, 3192 Target::eBroadcastBitBreakpointChanged); 3193 3194 BroadcastEventSpec process_event_spec (broadcaster_class_process, 3195 Process::eBroadcastBitStateChanged | 3196 Process::eBroadcastBitSTDOUT | 3197 Process::eBroadcastBitSTDERR); 3198 3199 BroadcastEventSpec thread_event_spec (broadcaster_class_thread, 3200 Thread::eBroadcastBitStackChanged | 3201 Thread::eBroadcastBitThreadSelected ); 3202 3203 listener.StartListeningForEventSpec (*this, target_event_spec); 3204 listener.StartListeningForEventSpec (*this, process_event_spec); 3205 listener.StartListeningForEventSpec (*this, thread_event_spec); 3206 listener.StartListeningForEvents (m_command_interpreter_ap.get(), 3207 CommandInterpreter::eBroadcastBitQuitCommandReceived | 3208 CommandInterpreter::eBroadcastBitAsynchronousOutputData | 3209 CommandInterpreter::eBroadcastBitAsynchronousErrorData ); 3210 3211 bool done = false; 3212 while (!done) 3213 { 3214 // Mutex::Locker locker; 3215 // if (locker.TryLock(m_input_reader_stack.GetMutex())) 3216 // { 3217 // if (m_input_reader_stack.IsEmpty()) 3218 // break; 3219 // } 3220 // 3221 EventSP event_sp; 3222 if (listener.WaitForEvent(NULL, event_sp)) 3223 { 3224 if (event_sp) 3225 { 3226 Broadcaster *broadcaster = event_sp->GetBroadcaster(); 3227 if (broadcaster) 3228 { 3229 uint32_t event_type = event_sp->GetType(); 3230 ConstString broadcaster_class (broadcaster->GetBroadcasterClass()); 3231 if (broadcaster_class == broadcaster_class_process) 3232 { 3233 HandleProcessEvent (event_sp); 3234 } 3235 else if (broadcaster_class == broadcaster_class_target) 3236 { 3237 if (Breakpoint::BreakpointEventData::GetEventDataFromEvent(event_sp.get())) 3238 { 3239 HandleBreakpointEvent (event_sp); 3240 } 3241 } 3242 else if (broadcaster_class == broadcaster_class_thread) 3243 { 3244 HandleThreadEvent (event_sp); 3245 } 3246 else if (broadcaster == m_command_interpreter_ap.get()) 3247 { 3248 if (event_type & CommandInterpreter::eBroadcastBitQuitCommandReceived) 3249 { 3250 done = true; 3251 } 3252 else if (event_type & CommandInterpreter::eBroadcastBitAsynchronousErrorData) 3253 { 3254 const char *data = reinterpret_cast<const char *>(EventDataBytes::GetBytesFromEvent (event_sp.get())); 3255 if (data && data[0]) 3256 { 3257 StreamFileSP error_sp (GetErrorFile()); 3258 if (error_sp) 3259 { 3260 HideTopIOHandler(); 3261 error_sp->PutCString(data); 3262 error_sp->Flush(); 3263 RefreshTopIOHandler(); 3264 } 3265 } 3266 } 3267 else if (event_type & CommandInterpreter::eBroadcastBitAsynchronousOutputData) 3268 { 3269 const char *data = reinterpret_cast<const char *>(EventDataBytes::GetBytesFromEvent (event_sp.get())); 3270 if (data && data[0]) 3271 { 3272 StreamFileSP output_sp (GetOutputFile()); 3273 if (output_sp) 3274 { 3275 HideTopIOHandler(); 3276 output_sp->PutCString(data); 3277 output_sp->Flush(); 3278 RefreshTopIOHandler(); 3279 } 3280 } 3281 } 3282 } 3283 } 3284 3285 if (m_forward_listener_sp) 3286 m_forward_listener_sp->AddEvent(event_sp); 3287 } 3288 } 3289 } 3290 } 3291 3292 lldb::thread_result_t 3293 Debugger::EventHandlerThread (lldb::thread_arg_t arg) 3294 { 3295 ((Debugger *)arg)->DefaultEventHandler(); 3296 return NULL; 3297 } 3298 3299 bool 3300 Debugger::StartEventHandlerThread() 3301 { 3302 if (!IS_VALID_LLDB_HOST_THREAD(m_event_handler_thread)) 3303 m_event_handler_thread = Host::ThreadCreate("lldb.debugger.event-handler", EventHandlerThread, this, NULL); 3304 return IS_VALID_LLDB_HOST_THREAD(m_event_handler_thread); 3305 } 3306 3307 void 3308 Debugger::StopEventHandlerThread() 3309 { 3310 if (IS_VALID_LLDB_HOST_THREAD(m_event_handler_thread)) 3311 { 3312 GetCommandInterpreter().BroadcastEvent(CommandInterpreter::eBroadcastBitQuitCommandReceived); 3313 Host::ThreadJoin(m_event_handler_thread, NULL, NULL); 3314 m_event_handler_thread = LLDB_INVALID_HOST_THREAD; 3315 } 3316 } 3317 3318 3319 lldb::thread_result_t 3320 Debugger::IOHandlerThread (lldb::thread_arg_t arg) 3321 { 3322 Debugger *debugger = (Debugger *)arg; 3323 debugger->ExecuteIOHanders(); 3324 debugger->StopEventHandlerThread(); 3325 return NULL; 3326 } 3327 3328 bool 3329 Debugger::StartIOHandlerThread() 3330 { 3331 if (!IS_VALID_LLDB_HOST_THREAD(m_io_handler_thread)) 3332 m_io_handler_thread = Host::ThreadCreate("lldb.debugger.io-handler", IOHandlerThread, this, NULL); 3333 return IS_VALID_LLDB_HOST_THREAD(m_io_handler_thread); 3334 } 3335 3336 void 3337 Debugger::StopIOHandlerThread() 3338 { 3339 if (IS_VALID_LLDB_HOST_THREAD(m_io_handler_thread)) 3340 { 3341 if (m_input_file_sp) 3342 m_input_file_sp->GetFile().Close(); 3343 Host::ThreadJoin(m_io_handler_thread, NULL, NULL); 3344 m_io_handler_thread = LLDB_INVALID_HOST_THREAD; 3345 } 3346 } 3347 3348 3349