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/Core/Debugger.h" 11 12 // C Includes 13 // C++ Includes 14 #include <map> 15 #include <mutex> 16 17 // Other libraries and framework includes 18 #include "llvm/ADT/StringRef.h" 19 #include "llvm/Support/DynamicLibrary.h" 20 21 // Project includes 22 #include "lldb/Core/FormatEntity.h" 23 #include "lldb/Core/Module.h" 24 #include "lldb/Core/PluginInterface.h" 25 #include "lldb/Core/PluginManager.h" 26 #include "lldb/Core/RegisterValue.h" 27 #include "lldb/Core/State.h" 28 #include "lldb/Core/StreamAsynchronousIO.h" 29 #include "lldb/Core/StreamCallback.h" 30 #include "lldb/Core/StreamFile.h" 31 #include "lldb/Core/StreamString.h" 32 #include "lldb/Core/StructuredData.h" 33 #include "lldb/Core/Timer.h" 34 #include "lldb/Core/ValueObject.h" 35 #include "lldb/Core/ValueObjectVariable.h" 36 #include "lldb/DataFormatters/DataVisualization.h" 37 #include "lldb/DataFormatters/FormatManager.h" 38 #include "lldb/DataFormatters/TypeSummary.h" 39 #include "lldb/Expression/REPL.h" 40 #include "lldb/Host/ConnectionFileDescriptor.h" 41 #include "lldb/Host/HostInfo.h" 42 #include "lldb/Host/Terminal.h" 43 #include "lldb/Host/ThreadLauncher.h" 44 #include "lldb/Interpreter/CommandInterpreter.h" 45 #include "lldb/Interpreter/OptionValueProperties.h" 46 #include "lldb/Interpreter/OptionValueSInt64.h" 47 #include "lldb/Interpreter/OptionValueString.h" 48 #include "lldb/Symbol/CompileUnit.h" 49 #include "lldb/Symbol/Function.h" 50 #include "lldb/Symbol/Symbol.h" 51 #include "lldb/Symbol/VariableList.h" 52 #include "lldb/Target/Language.h" 53 #include "lldb/Target/Process.h" 54 #include "lldb/Target/RegisterContext.h" 55 #include "lldb/Target/SectionLoadList.h" 56 #include "lldb/Target/StopInfo.h" 57 #include "lldb/Target/StructuredDataPlugin.h" 58 #include "lldb/Target/Target.h" 59 #include "lldb/Target/TargetList.h" 60 #include "lldb/Target/Thread.h" 61 #include "lldb/Utility/AnsiTerminal.h" 62 #include "lldb/lldb-private.h" 63 64 using namespace lldb; 65 using namespace lldb_private; 66 67 static lldb::user_id_t g_unique_id = 1; 68 static size_t g_debugger_event_thread_stack_bytes = 8 * 1024 * 1024; 69 70 #pragma mark Static Functions 71 72 typedef std::vector<DebuggerSP> DebuggerList; 73 static std::recursive_mutex *g_debugger_list_mutex_ptr = 74 nullptr; // NOTE: intentional leak to avoid issues with C++ destructor chain 75 static DebuggerList *g_debugger_list_ptr = 76 nullptr; // NOTE: intentional leak to avoid issues with C++ destructor chain 77 78 OptionEnumValueElement g_show_disassembly_enum_values[] = { 79 {Debugger::eStopDisassemblyTypeNever, "never", 80 "Never show disassembly when displaying a stop context."}, 81 {Debugger::eStopDisassemblyTypeNoDebugInfo, "no-debuginfo", 82 "Show disassembly when there is no debug information."}, 83 {Debugger::eStopDisassemblyTypeNoSource, "no-source", 84 "Show disassembly when there is no source information, or the source file " 85 "is missing when displaying a stop context."}, 86 {Debugger::eStopDisassemblyTypeAlways, "always", 87 "Always show disassembly when displaying a stop context."}, 88 {0, nullptr, nullptr}}; 89 90 OptionEnumValueElement g_language_enumerators[] = { 91 {eScriptLanguageNone, "none", "Disable scripting languages."}, 92 {eScriptLanguagePython, "python", 93 "Select python as the default scripting language."}, 94 {eScriptLanguageDefault, "default", 95 "Select the lldb default as the default scripting language."}, 96 {0, nullptr, nullptr}}; 97 98 #define MODULE_WITH_FUNC \ 99 "{ " \ 100 "${module.file.basename}{`${function.name-with-args}" \ 101 "{${frame.no-debug}${function.pc-offset}}}}" 102 #define FILE_AND_LINE "{ at ${line.file.basename}:${line.number}}" 103 #define IS_OPTIMIZED "{${function.is-optimized} [opt]}" 104 105 #define DEFAULT_THREAD_FORMAT \ 106 "thread #${thread.index}: tid = ${thread.id%tid}" \ 107 "{, ${frame.pc}}" MODULE_WITH_FUNC 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 "{\\nCompleted expression: ${thread.completed-expression}}" \ 115 "\\n" 116 117 #define DEFAULT_THREAD_STOP_FORMAT \ 118 "thread #${thread.index}{, name = '${thread.name}'}" \ 119 "{, queue = '${thread.queue}'}" \ 120 "{, activity = '${thread.info.activity.name}'}" \ 121 "{, ${thread.info.trace_messages} messages}" \ 122 "{, stop reason = ${thread.stop-reason}}" \ 123 "{\\nReturn value: ${thread.return-value}}" \ 124 "{\\nCompleted expression: ${thread.completed-expression}}" \ 125 "\\n" 126 127 #define DEFAULT_FRAME_FORMAT \ 128 "frame #${frame.index}:{ ${frame.no-debug}${frame.pc}}" MODULE_WITH_FUNC FILE_AND_LINE \ 129 IS_OPTIMIZED "\\n" 130 131 // Three parts to this disassembly format specification: 132 // 1. If this is a new function/symbol (no previous symbol/function), print 133 // dylib`funcname:\n 134 // 2. If this is a symbol context change (different from previous 135 // symbol/function), print 136 // dylib`funcname:\n 137 // 3. print 138 // address <+offset>: 139 #define DEFAULT_DISASSEMBLY_FORMAT \ 140 "{${function.initial-function}{${module.file.basename}`}{${function.name-" \ 141 "without-args}}:\n}{${function.changed}\n{${module.file.basename}`}{${" \ 142 "function.name-without-args}}:\n}{${current-pc-arrow} " \ 143 "}${addr-file-or-load}{ " \ 144 "<${function.concrete-only-addr-offset-no-padding}>}: " 145 146 // gdb's disassembly format can be emulated with 147 // ${current-pc-arrow}${addr-file-or-load}{ 148 // <${function.name-without-args}${function.concrete-only-addr-offset-no-padding}>}: 149 150 // lldb's original format for disassembly would look like this format string - 151 // {${function.initial-function}{${module.file.basename}`}{${function.name-without-args}}:\n}{${function.changed}\n{${module.file.basename}`}{${function.name-without-args}}:\n}{${current-pc-arrow} 152 // }{${addr-file-or-load}}: 153 154 #define DEFAULT_STOP_SHOW_COLUMN_ANSI_PREFIX "${ansi.underline}" 155 #define DEFAULT_STOP_SHOW_COLUMN_ANSI_SUFFIX "${ansi.normal}" 156 157 static OptionEnumValueElement s_stop_show_column_values[] = { 158 {eStopShowColumnAnsiOrCaret, "ansi-or-caret", 159 "Highlight the stop column with ANSI terminal codes when color/ANSI mode " 160 "is enabled; otherwise, fall back to using a text-only caret (^) as if " 161 "\"caret-only\" mode was selected."}, 162 {eStopShowColumnAnsi, "ansi", "Highlight the stop column with ANSI " 163 "terminal codes when running LLDB with " 164 "color/ANSI enabled."}, 165 {eStopShowColumnCaret, "caret", 166 "Highlight the stop column with a caret character (^) underneath the stop " 167 "column. This method introduces a new line in source listings that " 168 "display thread stop locations."}, 169 {eStopShowColumnNone, "none", "Do not highlight the stop column."}, 170 {0, nullptr, nullptr}}; 171 172 static PropertyDefinition g_properties[] = { 173 {"auto-confirm", OptionValue::eTypeBoolean, true, false, nullptr, nullptr, 174 "If true all confirmation prompts will receive their default reply."}, 175 {"disassembly-format", OptionValue::eTypeFormatEntity, true, 0, 176 DEFAULT_DISASSEMBLY_FORMAT, nullptr, "The default disassembly format " 177 "string to use when disassembling " 178 "instruction sequences."}, 179 {"frame-format", OptionValue::eTypeFormatEntity, true, 0, 180 DEFAULT_FRAME_FORMAT, nullptr, "The default frame format string to use " 181 "when displaying stack frame information " 182 "for threads."}, 183 {"notify-void", OptionValue::eTypeBoolean, true, false, nullptr, nullptr, 184 "Notify the user explicitly if an expression returns void (default: " 185 "false)."}, 186 {"prompt", OptionValue::eTypeString, true, 187 OptionValueString::eOptionEncodeCharacterEscapeSequences, "(lldb) ", 188 nullptr, "The debugger command line prompt displayed for the user."}, 189 {"script-lang", OptionValue::eTypeEnum, true, eScriptLanguagePython, 190 nullptr, g_language_enumerators, 191 "The script language to be used for evaluating user-written scripts."}, 192 {"stop-disassembly-count", OptionValue::eTypeSInt64, true, 4, nullptr, 193 nullptr, "The number of disassembly lines to show when displaying a " 194 "stopped context."}, 195 {"stop-disassembly-display", OptionValue::eTypeEnum, true, 196 Debugger::eStopDisassemblyTypeNoDebugInfo, nullptr, 197 g_show_disassembly_enum_values, 198 "Control when to display disassembly when displaying a stopped context."}, 199 {"stop-line-count-after", OptionValue::eTypeSInt64, true, 3, nullptr, 200 nullptr, "The number of sources lines to display that come after the " 201 "current source line when displaying a stopped context."}, 202 {"stop-line-count-before", OptionValue::eTypeSInt64, true, 3, nullptr, 203 nullptr, "The number of sources lines to display that come before the " 204 "current source line when displaying a stopped context."}, 205 {"stop-show-column", OptionValue::eTypeEnum, false, 206 eStopShowColumnAnsiOrCaret, nullptr, s_stop_show_column_values, 207 "If true, LLDB will use the column information from the debug info to " 208 "mark the current position when displaying a stopped context."}, 209 {"stop-show-column-ansi-prefix", OptionValue::eTypeFormatEntity, true, 0, 210 DEFAULT_STOP_SHOW_COLUMN_ANSI_PREFIX, nullptr, 211 "When displaying the column marker in a color-enabled (i.e. ANSI) " 212 "terminal, use the ANSI terminal code specified in this format at the " 213 "immediately before the column to be marked."}, 214 {"stop-show-column-ansi-suffix", OptionValue::eTypeFormatEntity, true, 0, 215 DEFAULT_STOP_SHOW_COLUMN_ANSI_SUFFIX, nullptr, 216 "When displaying the column marker in a color-enabled (i.e. ANSI) " 217 "terminal, use the ANSI terminal code specified in this format " 218 "immediately after the column to be marked."}, 219 {"term-width", OptionValue::eTypeSInt64, true, 80, nullptr, nullptr, 220 "The maximum number of columns to use for displaying text."}, 221 {"thread-format", OptionValue::eTypeFormatEntity, true, 0, 222 DEFAULT_THREAD_FORMAT, nullptr, "The default thread format string to use " 223 "when displaying thread information."}, 224 {"thread-stop-format", OptionValue::eTypeFormatEntity, true, 0, 225 DEFAULT_THREAD_STOP_FORMAT, nullptr, "The default thread format " 226 "string to usewhen displaying thread " 227 "information as part of the stop display."}, 228 {"use-external-editor", OptionValue::eTypeBoolean, true, false, nullptr, 229 nullptr, "Whether to use an external editor or not."}, 230 {"use-color", OptionValue::eTypeBoolean, true, true, nullptr, nullptr, 231 "Whether to use Ansi color codes or not."}, 232 {"auto-one-line-summaries", OptionValue::eTypeBoolean, true, true, nullptr, 233 nullptr, "If true, LLDB will automatically display small structs in " 234 "one-liner format (default: true)."}, 235 {"auto-indent", OptionValue::eTypeBoolean, true, true, nullptr, nullptr, 236 "If true, LLDB will auto indent/outdent code. Currently only supported in " 237 "the REPL (default: true)."}, 238 {"print-decls", OptionValue::eTypeBoolean, true, true, nullptr, nullptr, 239 "If true, LLDB will print the values of variables declared in an " 240 "expression. Currently only supported in the REPL (default: true)."}, 241 {"tab-size", OptionValue::eTypeUInt64, true, 4, nullptr, nullptr, 242 "The tab size to use when indenting code in multi-line input mode " 243 "(default: 4)."}, 244 {"escape-non-printables", OptionValue::eTypeBoolean, true, true, nullptr, 245 nullptr, "If true, LLDB will automatically escape non-printable and " 246 "escape characters when formatting strings."}, 247 {nullptr, OptionValue::eTypeInvalid, true, 0, nullptr, nullptr, nullptr}}; 248 249 enum { 250 ePropertyAutoConfirm = 0, 251 ePropertyDisassemblyFormat, 252 ePropertyFrameFormat, 253 ePropertyNotiftVoid, 254 ePropertyPrompt, 255 ePropertyScriptLanguage, 256 ePropertyStopDisassemblyCount, 257 ePropertyStopDisassemblyDisplay, 258 ePropertyStopLineCountAfter, 259 ePropertyStopLineCountBefore, 260 ePropertyStopShowColumn, 261 ePropertyStopShowColumnAnsiPrefix, 262 ePropertyStopShowColumnAnsiSuffix, 263 ePropertyTerminalWidth, 264 ePropertyThreadFormat, 265 ePropertyThreadStopFormat, 266 ePropertyUseExternalEditor, 267 ePropertyUseColor, 268 ePropertyAutoOneLineSummaries, 269 ePropertyAutoIndent, 270 ePropertyPrintDecls, 271 ePropertyTabSize, 272 ePropertyEscapeNonPrintables 273 }; 274 275 LoadPluginCallbackType Debugger::g_load_plugin_callback = nullptr; 276 277 Error Debugger::SetPropertyValue(const ExecutionContext *exe_ctx, 278 VarSetOperationType op, 279 llvm::StringRef property_path, llvm::StringRef value) { 280 bool is_load_script = (property_path == "target.load-script-from-symbol-file"); 281 bool is_escape_non_printables = (property_path == "escape-non-printables"); 282 TargetSP target_sp; 283 LoadScriptFromSymFile load_script_old_value; 284 if (is_load_script && exe_ctx->GetTargetSP()) { 285 target_sp = exe_ctx->GetTargetSP(); 286 load_script_old_value = 287 target_sp->TargetProperties::GetLoadScriptFromSymbolFile(); 288 } 289 Error error(Properties::SetPropertyValue(exe_ctx, op, property_path, value)); 290 if (error.Success()) { 291 // FIXME it would be nice to have "on-change" callbacks for properties 292 if (property_path == g_properties[ePropertyPrompt].name) { 293 llvm::StringRef new_prompt = GetPrompt(); 294 std::string str = lldb_utility::ansi::FormatAnsiTerminalCodes( 295 new_prompt, GetUseColor()); 296 if (str.length()) 297 new_prompt = str; 298 GetCommandInterpreter().UpdatePrompt(new_prompt); 299 EventSP prompt_change_event_sp( 300 new Event(CommandInterpreter::eBroadcastBitResetPrompt, 301 new EventDataBytes(new_prompt))); 302 GetCommandInterpreter().BroadcastEvent(prompt_change_event_sp); 303 } else if (property_path == g_properties[ePropertyUseColor].name) { 304 // use-color changed. Ping the prompt so it can reset the ansi terminal 305 // codes. 306 SetPrompt(GetPrompt()); 307 } else if (is_load_script && target_sp && 308 load_script_old_value == eLoadScriptFromSymFileWarn) { 309 if (target_sp->TargetProperties::GetLoadScriptFromSymbolFile() == 310 eLoadScriptFromSymFileTrue) { 311 std::list<Error> errors; 312 StreamString feedback_stream; 313 if (!target_sp->LoadScriptingResources(errors, &feedback_stream)) { 314 StreamFileSP stream_sp(GetErrorFile()); 315 if (stream_sp) { 316 for (auto error : errors) { 317 stream_sp->Printf("%s\n", error.AsCString()); 318 } 319 if (feedback_stream.GetSize()) 320 stream_sp->PutCString(feedback_stream.GetString()); 321 } 322 } 323 } 324 } else if (is_escape_non_printables) { 325 DataVisualization::ForceUpdate(); 326 } 327 } 328 return error; 329 } 330 331 bool Debugger::GetAutoConfirm() const { 332 const uint32_t idx = ePropertyAutoConfirm; 333 return m_collection_sp->GetPropertyAtIndexAsBoolean( 334 nullptr, idx, g_properties[idx].default_uint_value != 0); 335 } 336 337 const FormatEntity::Entry *Debugger::GetDisassemblyFormat() const { 338 const uint32_t idx = ePropertyDisassemblyFormat; 339 return m_collection_sp->GetPropertyAtIndexAsFormatEntity(nullptr, idx); 340 } 341 342 const FormatEntity::Entry *Debugger::GetFrameFormat() const { 343 const uint32_t idx = ePropertyFrameFormat; 344 return m_collection_sp->GetPropertyAtIndexAsFormatEntity(nullptr, idx); 345 } 346 347 bool Debugger::GetNotifyVoid() const { 348 const uint32_t idx = ePropertyNotiftVoid; 349 return m_collection_sp->GetPropertyAtIndexAsBoolean( 350 nullptr, idx, g_properties[idx].default_uint_value != 0); 351 } 352 353 llvm::StringRef Debugger::GetPrompt() const { 354 const uint32_t idx = ePropertyPrompt; 355 return m_collection_sp->GetPropertyAtIndexAsString( 356 nullptr, idx, g_properties[idx].default_cstr_value); 357 } 358 359 void Debugger::SetPrompt(llvm::StringRef p) { 360 const uint32_t idx = ePropertyPrompt; 361 m_collection_sp->SetPropertyAtIndexAsString(nullptr, idx, p); 362 llvm::StringRef new_prompt = GetPrompt(); 363 std::string str = 364 lldb_utility::ansi::FormatAnsiTerminalCodes(new_prompt, GetUseColor()); 365 if (str.length()) 366 new_prompt = str; 367 GetCommandInterpreter().UpdatePrompt(new_prompt); 368 } 369 370 const FormatEntity::Entry *Debugger::GetThreadFormat() const { 371 const uint32_t idx = ePropertyThreadFormat; 372 return m_collection_sp->GetPropertyAtIndexAsFormatEntity(nullptr, idx); 373 } 374 375 const FormatEntity::Entry *Debugger::GetThreadStopFormat() const { 376 const uint32_t idx = ePropertyThreadStopFormat; 377 return m_collection_sp->GetPropertyAtIndexAsFormatEntity(nullptr, idx); 378 } 379 380 lldb::ScriptLanguage Debugger::GetScriptLanguage() const { 381 const uint32_t idx = ePropertyScriptLanguage; 382 return (lldb::ScriptLanguage)m_collection_sp->GetPropertyAtIndexAsEnumeration( 383 nullptr, idx, g_properties[idx].default_uint_value); 384 } 385 386 bool Debugger::SetScriptLanguage(lldb::ScriptLanguage script_lang) { 387 const uint32_t idx = ePropertyScriptLanguage; 388 return m_collection_sp->SetPropertyAtIndexAsEnumeration(nullptr, idx, 389 script_lang); 390 } 391 392 uint32_t Debugger::GetTerminalWidth() const { 393 const uint32_t idx = ePropertyTerminalWidth; 394 return m_collection_sp->GetPropertyAtIndexAsSInt64( 395 nullptr, idx, g_properties[idx].default_uint_value); 396 } 397 398 bool Debugger::SetTerminalWidth(uint32_t term_width) { 399 const uint32_t idx = ePropertyTerminalWidth; 400 return m_collection_sp->SetPropertyAtIndexAsSInt64(nullptr, idx, term_width); 401 } 402 403 bool Debugger::GetUseExternalEditor() const { 404 const uint32_t idx = ePropertyUseExternalEditor; 405 return m_collection_sp->GetPropertyAtIndexAsBoolean( 406 nullptr, idx, g_properties[idx].default_uint_value != 0); 407 } 408 409 bool Debugger::SetUseExternalEditor(bool b) { 410 const uint32_t idx = ePropertyUseExternalEditor; 411 return m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b); 412 } 413 414 bool Debugger::GetUseColor() const { 415 const uint32_t idx = ePropertyUseColor; 416 return m_collection_sp->GetPropertyAtIndexAsBoolean( 417 nullptr, idx, g_properties[idx].default_uint_value != 0); 418 } 419 420 bool Debugger::SetUseColor(bool b) { 421 const uint32_t idx = ePropertyUseColor; 422 bool ret = m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b); 423 SetPrompt(GetPrompt()); 424 return ret; 425 } 426 427 StopShowColumn Debugger::GetStopShowColumn() const { 428 const uint32_t idx = ePropertyStopShowColumn; 429 return (lldb::StopShowColumn)m_collection_sp->GetPropertyAtIndexAsEnumeration( 430 nullptr, idx, g_properties[idx].default_uint_value); 431 } 432 433 const FormatEntity::Entry *Debugger::GetStopShowColumnAnsiPrefix() const { 434 const uint32_t idx = ePropertyStopShowColumnAnsiPrefix; 435 return m_collection_sp->GetPropertyAtIndexAsFormatEntity(nullptr, idx); 436 } 437 438 const FormatEntity::Entry *Debugger::GetStopShowColumnAnsiSuffix() const { 439 const uint32_t idx = ePropertyStopShowColumnAnsiSuffix; 440 return m_collection_sp->GetPropertyAtIndexAsFormatEntity(nullptr, idx); 441 } 442 443 uint32_t Debugger::GetStopSourceLineCount(bool before) const { 444 const uint32_t idx = 445 before ? ePropertyStopLineCountBefore : ePropertyStopLineCountAfter; 446 return m_collection_sp->GetPropertyAtIndexAsSInt64( 447 nullptr, idx, g_properties[idx].default_uint_value); 448 } 449 450 Debugger::StopDisassemblyType Debugger::GetStopDisassemblyDisplay() const { 451 const uint32_t idx = ePropertyStopDisassemblyDisplay; 452 return (Debugger::StopDisassemblyType) 453 m_collection_sp->GetPropertyAtIndexAsEnumeration( 454 nullptr, idx, g_properties[idx].default_uint_value); 455 } 456 457 uint32_t Debugger::GetDisassemblyLineCount() const { 458 const uint32_t idx = ePropertyStopDisassemblyCount; 459 return m_collection_sp->GetPropertyAtIndexAsSInt64( 460 nullptr, idx, g_properties[idx].default_uint_value); 461 } 462 463 bool Debugger::GetAutoOneLineSummaries() const { 464 const uint32_t idx = ePropertyAutoOneLineSummaries; 465 return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, true); 466 } 467 468 bool Debugger::GetEscapeNonPrintables() const { 469 const uint32_t idx = ePropertyEscapeNonPrintables; 470 return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, true); 471 } 472 473 bool Debugger::GetAutoIndent() const { 474 const uint32_t idx = ePropertyAutoIndent; 475 return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, true); 476 } 477 478 bool Debugger::SetAutoIndent(bool b) { 479 const uint32_t idx = ePropertyAutoIndent; 480 return m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b); 481 } 482 483 bool Debugger::GetPrintDecls() const { 484 const uint32_t idx = ePropertyPrintDecls; 485 return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, true); 486 } 487 488 bool Debugger::SetPrintDecls(bool b) { 489 const uint32_t idx = ePropertyPrintDecls; 490 return m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b); 491 } 492 493 uint32_t Debugger::GetTabSize() const { 494 const uint32_t idx = ePropertyTabSize; 495 return m_collection_sp->GetPropertyAtIndexAsUInt64( 496 nullptr, idx, g_properties[idx].default_uint_value); 497 } 498 499 bool Debugger::SetTabSize(uint32_t tab_size) { 500 const uint32_t idx = ePropertyTabSize; 501 return m_collection_sp->SetPropertyAtIndexAsUInt64(nullptr, idx, tab_size); 502 } 503 504 #pragma mark Debugger 505 506 // const DebuggerPropertiesSP & 507 // Debugger::GetSettings() const 508 //{ 509 // return m_properties_sp; 510 //} 511 // 512 513 void Debugger::Initialize(LoadPluginCallbackType load_plugin_callback) { 514 assert(g_debugger_list_ptr == nullptr && 515 "Debugger::Initialize called more than once!"); 516 g_debugger_list_mutex_ptr = new std::recursive_mutex(); 517 g_debugger_list_ptr = new DebuggerList(); 518 g_load_plugin_callback = load_plugin_callback; 519 } 520 521 void Debugger::Terminate() { 522 assert(g_debugger_list_ptr && 523 "Debugger::Terminate called without a matching Debugger::Initialize!"); 524 525 if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) { 526 // Clear our master list of debugger objects 527 { 528 std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr); 529 for (const auto &debugger : *g_debugger_list_ptr) 530 debugger->Clear(); 531 g_debugger_list_ptr->clear(); 532 } 533 } 534 } 535 536 void Debugger::SettingsInitialize() { Target::SettingsInitialize(); } 537 538 void Debugger::SettingsTerminate() { Target::SettingsTerminate(); } 539 540 bool Debugger::LoadPlugin(const FileSpec &spec, Error &error) { 541 if (g_load_plugin_callback) { 542 llvm::sys::DynamicLibrary dynlib = 543 g_load_plugin_callback(shared_from_this(), spec, error); 544 if (dynlib.isValid()) { 545 m_loaded_plugins.push_back(dynlib); 546 return true; 547 } 548 } else { 549 // The g_load_plugin_callback is registered in SBDebugger::Initialize() 550 // and if the public API layer isn't available (code is linking against 551 // all of the internal LLDB static libraries), then we can't load plugins 552 error.SetErrorString("Public API layer is not available"); 553 } 554 return false; 555 } 556 557 static FileSpec::EnumerateDirectoryResult 558 LoadPluginCallback(void *baton, FileSpec::FileType file_type, 559 const FileSpec &file_spec) { 560 Error error; 561 562 static ConstString g_dylibext("dylib"); 563 static ConstString g_solibext("so"); 564 565 if (!baton) 566 return FileSpec::eEnumerateDirectoryResultQuit; 567 568 Debugger *debugger = (Debugger *)baton; 569 570 // If we have a regular file, a symbolic link or unknown file type, try 571 // and process the file. We must handle unknown as sometimes the directory 572 // enumeration might be enumerating a file system that doesn't have correct 573 // file type information. 574 if (file_type == FileSpec::eFileTypeRegular || 575 file_type == FileSpec::eFileTypeSymbolicLink || 576 file_type == FileSpec::eFileTypeUnknown) { 577 FileSpec plugin_file_spec(file_spec); 578 plugin_file_spec.ResolvePath(); 579 580 if (plugin_file_spec.GetFileNameExtension() != g_dylibext && 581 plugin_file_spec.GetFileNameExtension() != g_solibext) { 582 return FileSpec::eEnumerateDirectoryResultNext; 583 } 584 585 Error plugin_load_error; 586 debugger->LoadPlugin(plugin_file_spec, plugin_load_error); 587 588 return FileSpec::eEnumerateDirectoryResultNext; 589 } else if (file_type == FileSpec::eFileTypeUnknown || 590 file_type == FileSpec::eFileTypeDirectory || 591 file_type == FileSpec::eFileTypeSymbolicLink) { 592 // Try and recurse into anything that a directory or symbolic link. 593 // We must also do this for unknown as sometimes the directory enumeration 594 // might be enumerating a file system that doesn't have correct file type 595 // information. 596 return FileSpec::eEnumerateDirectoryResultEnter; 597 } 598 599 return FileSpec::eEnumerateDirectoryResultNext; 600 } 601 602 void Debugger::InstanceInitialize() { 603 FileSpec dir_spec; 604 const bool find_directories = true; 605 const bool find_files = true; 606 const bool find_other = true; 607 char dir_path[PATH_MAX]; 608 if (HostInfo::GetLLDBPath(ePathTypeLLDBSystemPlugins, dir_spec)) { 609 if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path))) { 610 FileSpec::EnumerateDirectory(dir_path, find_directories, find_files, 611 find_other, LoadPluginCallback, this); 612 } 613 } 614 615 if (HostInfo::GetLLDBPath(ePathTypeLLDBUserPlugins, dir_spec)) { 616 if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path))) { 617 FileSpec::EnumerateDirectory(dir_path, find_directories, find_files, 618 find_other, LoadPluginCallback, this); 619 } 620 } 621 622 PluginManager::DebuggerInitialize(*this); 623 } 624 625 DebuggerSP Debugger::CreateInstance(lldb::LogOutputCallback log_callback, 626 void *baton) { 627 DebuggerSP debugger_sp(new Debugger(log_callback, baton)); 628 if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) { 629 std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr); 630 g_debugger_list_ptr->push_back(debugger_sp); 631 } 632 debugger_sp->InstanceInitialize(); 633 return debugger_sp; 634 } 635 636 void Debugger::Destroy(DebuggerSP &debugger_sp) { 637 if (!debugger_sp) 638 return; 639 640 debugger_sp->Clear(); 641 642 if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) { 643 std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr); 644 DebuggerList::iterator pos, end = g_debugger_list_ptr->end(); 645 for (pos = g_debugger_list_ptr->begin(); pos != end; ++pos) { 646 if ((*pos).get() == debugger_sp.get()) { 647 g_debugger_list_ptr->erase(pos); 648 return; 649 } 650 } 651 } 652 } 653 654 DebuggerSP 655 Debugger::FindDebuggerWithInstanceName(const ConstString &instance_name) { 656 DebuggerSP debugger_sp; 657 if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) { 658 std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr); 659 DebuggerList::iterator pos, end = g_debugger_list_ptr->end(); 660 for (pos = g_debugger_list_ptr->begin(); pos != end; ++pos) { 661 if ((*pos)->m_instance_name == instance_name) { 662 debugger_sp = *pos; 663 break; 664 } 665 } 666 } 667 return debugger_sp; 668 } 669 670 TargetSP Debugger::FindTargetWithProcessID(lldb::pid_t pid) { 671 TargetSP target_sp; 672 if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) { 673 std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr); 674 DebuggerList::iterator pos, end = g_debugger_list_ptr->end(); 675 for (pos = g_debugger_list_ptr->begin(); pos != end; ++pos) { 676 target_sp = (*pos)->GetTargetList().FindTargetWithProcessID(pid); 677 if (target_sp) 678 break; 679 } 680 } 681 return target_sp; 682 } 683 684 TargetSP Debugger::FindTargetWithProcess(Process *process) { 685 TargetSP target_sp; 686 if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) { 687 std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr); 688 DebuggerList::iterator pos, end = g_debugger_list_ptr->end(); 689 for (pos = g_debugger_list_ptr->begin(); pos != end; ++pos) { 690 target_sp = (*pos)->GetTargetList().FindTargetWithProcess(process); 691 if (target_sp) 692 break; 693 } 694 } 695 return target_sp; 696 } 697 698 Debugger::Debugger(lldb::LogOutputCallback log_callback, void *baton) 699 : UserID(g_unique_id++), 700 Properties(OptionValuePropertiesSP(new OptionValueProperties())), 701 m_input_file_sp(new StreamFile(stdin, false)), 702 m_output_file_sp(new StreamFile(stdout, false)), 703 m_error_file_sp(new StreamFile(stderr, false)), 704 m_broadcaster_manager_sp(BroadcasterManager::MakeBroadcasterManager()), 705 m_terminal_state(), m_target_list(*this), m_platform_list(), 706 m_listener_sp(Listener::MakeListener("lldb.Debugger")), 707 m_source_manager_ap(), m_source_file_cache(), 708 m_command_interpreter_ap( 709 new CommandInterpreter(*this, eScriptLanguageDefault, false)), 710 m_input_reader_stack(), m_instance_name(), m_loaded_plugins(), 711 m_event_handler_thread(), m_io_handler_thread(), 712 m_sync_broadcaster(nullptr, "lldb.debugger.sync"), 713 m_forward_listener_sp(), m_clear_once() { 714 char instance_cstr[256]; 715 snprintf(instance_cstr, sizeof(instance_cstr), "debugger_%d", (int)GetID()); 716 m_instance_name.SetCString(instance_cstr); 717 if (log_callback) 718 m_log_callback_stream_sp.reset(new StreamCallback(log_callback, baton)); 719 m_command_interpreter_ap->Initialize(); 720 // Always add our default platform to the platform list 721 PlatformSP default_platform_sp(Platform::GetHostPlatform()); 722 assert(default_platform_sp); 723 m_platform_list.Append(default_platform_sp, true); 724 725 m_collection_sp->Initialize(g_properties); 726 m_collection_sp->AppendProperty( 727 ConstString("target"), 728 ConstString("Settings specify to debugging targets."), true, 729 Target::GetGlobalProperties()->GetValueProperties()); 730 m_collection_sp->AppendProperty( 731 ConstString("platform"), ConstString("Platform settings."), true, 732 Platform::GetGlobalPlatformProperties()->GetValueProperties()); 733 if (m_command_interpreter_ap) { 734 m_collection_sp->AppendProperty( 735 ConstString("interpreter"), 736 ConstString("Settings specify to the debugger's command interpreter."), 737 true, m_command_interpreter_ap->GetValueProperties()); 738 } 739 OptionValueSInt64 *term_width = 740 m_collection_sp->GetPropertyAtIndexAsOptionValueSInt64( 741 nullptr, ePropertyTerminalWidth); 742 term_width->SetMinimumValue(10); 743 term_width->SetMaximumValue(1024); 744 745 // Turn off use-color if this is a dumb terminal. 746 const char *term = getenv("TERM"); 747 if (term && !strcmp(term, "dumb")) 748 SetUseColor(false); 749 } 750 751 Debugger::~Debugger() { Clear(); } 752 753 void Debugger::Clear() { 754 //---------------------------------------------------------------------- 755 // Make sure we call this function only once. With the C++ global 756 // destructor chain having a list of debuggers and with code that can be 757 // running on other threads, we need to ensure this doesn't happen 758 // multiple times. 759 // 760 // The following functions call Debugger::Clear(): 761 // Debugger::~Debugger(); 762 // static void Debugger::Destroy(lldb::DebuggerSP &debugger_sp); 763 // static void Debugger::Terminate(); 764 //---------------------------------------------------------------------- 765 std::call_once(m_clear_once, [this]() { 766 ClearIOHandlers(); 767 StopIOHandlerThread(); 768 StopEventHandlerThread(); 769 m_listener_sp->Clear(); 770 int num_targets = m_target_list.GetNumTargets(); 771 for (int i = 0; i < num_targets; i++) { 772 TargetSP target_sp(m_target_list.GetTargetAtIndex(i)); 773 if (target_sp) { 774 ProcessSP process_sp(target_sp->GetProcessSP()); 775 if (process_sp) 776 process_sp->Finalize(); 777 target_sp->Destroy(); 778 } 779 } 780 m_broadcaster_manager_sp->Clear(); 781 782 // Close the input file _before_ we close the input read communications 783 // class 784 // as it does NOT own the input file, our m_input_file does. 785 m_terminal_state.Clear(); 786 if (m_input_file_sp) 787 m_input_file_sp->GetFile().Close(); 788 789 m_command_interpreter_ap->Clear(); 790 }); 791 } 792 793 bool Debugger::GetCloseInputOnEOF() const { 794 // return m_input_comm.GetCloseOnEOF(); 795 return false; 796 } 797 798 void Debugger::SetCloseInputOnEOF(bool b) { 799 // m_input_comm.SetCloseOnEOF(b); 800 } 801 802 bool Debugger::GetAsyncExecution() { 803 return !m_command_interpreter_ap->GetSynchronous(); 804 } 805 806 void Debugger::SetAsyncExecution(bool async_execution) { 807 m_command_interpreter_ap->SetSynchronous(!async_execution); 808 } 809 810 void Debugger::SetInputFileHandle(FILE *fh, bool tranfer_ownership) { 811 if (m_input_file_sp) 812 m_input_file_sp->GetFile().SetStream(fh, tranfer_ownership); 813 else 814 m_input_file_sp.reset(new StreamFile(fh, tranfer_ownership)); 815 816 File &in_file = m_input_file_sp->GetFile(); 817 if (!in_file.IsValid()) 818 in_file.SetStream(stdin, true); 819 820 // Save away the terminal state if that is relevant, so that we can restore it 821 // in RestoreInputState. 822 SaveInputTerminalState(); 823 } 824 825 void Debugger::SetOutputFileHandle(FILE *fh, bool tranfer_ownership) { 826 if (m_output_file_sp) 827 m_output_file_sp->GetFile().SetStream(fh, tranfer_ownership); 828 else 829 m_output_file_sp.reset(new StreamFile(fh, tranfer_ownership)); 830 831 File &out_file = m_output_file_sp->GetFile(); 832 if (!out_file.IsValid()) 833 out_file.SetStream(stdout, false); 834 835 // do not create the ScriptInterpreter just for setting the output file handle 836 // as the constructor will know how to do the right thing on its own 837 const bool can_create = false; 838 ScriptInterpreter *script_interpreter = 839 GetCommandInterpreter().GetScriptInterpreter(can_create); 840 if (script_interpreter) 841 script_interpreter->ResetOutputFileHandle(fh); 842 } 843 844 void Debugger::SetErrorFileHandle(FILE *fh, bool tranfer_ownership) { 845 if (m_error_file_sp) 846 m_error_file_sp->GetFile().SetStream(fh, tranfer_ownership); 847 else 848 m_error_file_sp.reset(new StreamFile(fh, tranfer_ownership)); 849 850 File &err_file = m_error_file_sp->GetFile(); 851 if (!err_file.IsValid()) 852 err_file.SetStream(stderr, false); 853 } 854 855 void Debugger::SaveInputTerminalState() { 856 if (m_input_file_sp) { 857 File &in_file = m_input_file_sp->GetFile(); 858 if (in_file.GetDescriptor() != File::kInvalidDescriptor) 859 m_terminal_state.Save(in_file.GetDescriptor(), true); 860 } 861 } 862 863 void Debugger::RestoreInputTerminalState() { m_terminal_state.Restore(); } 864 865 ExecutionContext Debugger::GetSelectedExecutionContext() { 866 ExecutionContext exe_ctx; 867 TargetSP target_sp(GetSelectedTarget()); 868 exe_ctx.SetTargetSP(target_sp); 869 870 if (target_sp) { 871 ProcessSP process_sp(target_sp->GetProcessSP()); 872 exe_ctx.SetProcessSP(process_sp); 873 if (process_sp && !process_sp->IsRunning()) { 874 ThreadSP thread_sp(process_sp->GetThreadList().GetSelectedThread()); 875 if (thread_sp) { 876 exe_ctx.SetThreadSP(thread_sp); 877 exe_ctx.SetFrameSP(thread_sp->GetSelectedFrame()); 878 if (exe_ctx.GetFramePtr() == nullptr) 879 exe_ctx.SetFrameSP(thread_sp->GetStackFrameAtIndex(0)); 880 } 881 } 882 } 883 return exe_ctx; 884 } 885 886 void Debugger::DispatchInputInterrupt() { 887 std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex()); 888 IOHandlerSP reader_sp(m_input_reader_stack.Top()); 889 if (reader_sp) 890 reader_sp->Interrupt(); 891 } 892 893 void Debugger::DispatchInputEndOfFile() { 894 std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex()); 895 IOHandlerSP reader_sp(m_input_reader_stack.Top()); 896 if (reader_sp) 897 reader_sp->GotEOF(); 898 } 899 900 void Debugger::ClearIOHandlers() { 901 // The bottom input reader should be the main debugger input reader. We do 902 // not want to close that one here. 903 std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex()); 904 while (m_input_reader_stack.GetSize() > 1) { 905 IOHandlerSP reader_sp(m_input_reader_stack.Top()); 906 if (reader_sp) 907 PopIOHandler(reader_sp); 908 } 909 } 910 911 void Debugger::ExecuteIOHandlers() { 912 while (true) { 913 IOHandlerSP reader_sp(m_input_reader_stack.Top()); 914 if (!reader_sp) 915 break; 916 917 reader_sp->Run(); 918 919 // Remove all input readers that are done from the top of the stack 920 while (true) { 921 IOHandlerSP top_reader_sp = m_input_reader_stack.Top(); 922 if (top_reader_sp && top_reader_sp->GetIsDone()) 923 PopIOHandler(top_reader_sp); 924 else 925 break; 926 } 927 } 928 ClearIOHandlers(); 929 } 930 931 bool Debugger::IsTopIOHandler(const lldb::IOHandlerSP &reader_sp) { 932 return m_input_reader_stack.IsTop(reader_sp); 933 } 934 935 bool Debugger::CheckTopIOHandlerTypes(IOHandler::Type top_type, 936 IOHandler::Type second_top_type) { 937 return m_input_reader_stack.CheckTopIOHandlerTypes(top_type, second_top_type); 938 } 939 940 void Debugger::PrintAsync(const char *s, size_t len, bool is_stdout) { 941 lldb::StreamFileSP stream = is_stdout ? GetOutputFile() : GetErrorFile(); 942 m_input_reader_stack.PrintAsync(stream.get(), s, len); 943 } 944 945 ConstString Debugger::GetTopIOHandlerControlSequence(char ch) { 946 return m_input_reader_stack.GetTopIOHandlerControlSequence(ch); 947 } 948 949 const char *Debugger::GetIOHandlerCommandPrefix() { 950 return m_input_reader_stack.GetTopIOHandlerCommandPrefix(); 951 } 952 953 const char *Debugger::GetIOHandlerHelpPrologue() { 954 return m_input_reader_stack.GetTopIOHandlerHelpPrologue(); 955 } 956 957 void Debugger::RunIOHandler(const IOHandlerSP &reader_sp) { 958 PushIOHandler(reader_sp); 959 960 IOHandlerSP top_reader_sp = reader_sp; 961 while (top_reader_sp) { 962 top_reader_sp->Run(); 963 964 if (top_reader_sp.get() == reader_sp.get()) { 965 if (PopIOHandler(reader_sp)) 966 break; 967 } 968 969 while (true) { 970 top_reader_sp = m_input_reader_stack.Top(); 971 if (top_reader_sp && top_reader_sp->GetIsDone()) 972 PopIOHandler(top_reader_sp); 973 else 974 break; 975 } 976 } 977 } 978 979 void Debugger::AdoptTopIOHandlerFilesIfInvalid(StreamFileSP &in, 980 StreamFileSP &out, 981 StreamFileSP &err) { 982 // Before an IOHandler runs, it must have in/out/err streams. 983 // This function is called when one ore more of the streams 984 // are nullptr. We use the top input reader's in/out/err streams, 985 // or fall back to the debugger file handles, or we fall back 986 // onto stdin/stdout/stderr as a last resort. 987 988 std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex()); 989 IOHandlerSP top_reader_sp(m_input_reader_stack.Top()); 990 // If no STDIN has been set, then set it appropriately 991 if (!in) { 992 if (top_reader_sp) 993 in = top_reader_sp->GetInputStreamFile(); 994 else 995 in = GetInputFile(); 996 997 // If there is nothing, use stdin 998 if (!in) 999 in = StreamFileSP(new StreamFile(stdin, false)); 1000 } 1001 // If no STDOUT has been set, then set it appropriately 1002 if (!out) { 1003 if (top_reader_sp) 1004 out = top_reader_sp->GetOutputStreamFile(); 1005 else 1006 out = GetOutputFile(); 1007 1008 // If there is nothing, use stdout 1009 if (!out) 1010 out = StreamFileSP(new StreamFile(stdout, false)); 1011 } 1012 // If no STDERR has been set, then set it appropriately 1013 if (!err) { 1014 if (top_reader_sp) 1015 err = top_reader_sp->GetErrorStreamFile(); 1016 else 1017 err = GetErrorFile(); 1018 1019 // If there is nothing, use stderr 1020 if (!err) 1021 err = StreamFileSP(new StreamFile(stdout, false)); 1022 } 1023 } 1024 1025 void Debugger::PushIOHandler(const IOHandlerSP &reader_sp) { 1026 if (!reader_sp) 1027 return; 1028 1029 std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex()); 1030 1031 // Get the current top input reader... 1032 IOHandlerSP top_reader_sp(m_input_reader_stack.Top()); 1033 1034 // Don't push the same IO handler twice... 1035 if (reader_sp == top_reader_sp) 1036 return; 1037 1038 // Push our new input reader 1039 m_input_reader_stack.Push(reader_sp); 1040 reader_sp->Activate(); 1041 1042 // Interrupt the top input reader to it will exit its Run() function 1043 // and let this new input reader take over 1044 if (top_reader_sp) { 1045 top_reader_sp->Deactivate(); 1046 top_reader_sp->Cancel(); 1047 } 1048 } 1049 1050 bool Debugger::PopIOHandler(const IOHandlerSP &pop_reader_sp) { 1051 if (!pop_reader_sp) 1052 return false; 1053 1054 std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex()); 1055 1056 // The reader on the stop of the stack is done, so let the next 1057 // read on the stack refresh its prompt and if there is one... 1058 if (m_input_reader_stack.IsEmpty()) 1059 return false; 1060 1061 IOHandlerSP reader_sp(m_input_reader_stack.Top()); 1062 1063 if (pop_reader_sp != reader_sp) 1064 return false; 1065 1066 reader_sp->Deactivate(); 1067 reader_sp->Cancel(); 1068 m_input_reader_stack.Pop(); 1069 1070 reader_sp = m_input_reader_stack.Top(); 1071 if (reader_sp) 1072 reader_sp->Activate(); 1073 1074 return true; 1075 } 1076 1077 StreamSP Debugger::GetAsyncOutputStream() { 1078 return StreamSP(new StreamAsynchronousIO(*this, true)); 1079 } 1080 1081 StreamSP Debugger::GetAsyncErrorStream() { 1082 return StreamSP(new StreamAsynchronousIO(*this, false)); 1083 } 1084 1085 size_t Debugger::GetNumDebuggers() { 1086 if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) { 1087 std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr); 1088 return g_debugger_list_ptr->size(); 1089 } 1090 return 0; 1091 } 1092 1093 lldb::DebuggerSP Debugger::GetDebuggerAtIndex(size_t index) { 1094 DebuggerSP debugger_sp; 1095 1096 if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) { 1097 std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr); 1098 if (index < g_debugger_list_ptr->size()) 1099 debugger_sp = g_debugger_list_ptr->at(index); 1100 } 1101 1102 return debugger_sp; 1103 } 1104 1105 DebuggerSP Debugger::FindDebuggerWithID(lldb::user_id_t id) { 1106 DebuggerSP debugger_sp; 1107 1108 if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) { 1109 std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr); 1110 DebuggerList::iterator pos, end = g_debugger_list_ptr->end(); 1111 for (pos = g_debugger_list_ptr->begin(); pos != end; ++pos) { 1112 if ((*pos)->GetID() == id) { 1113 debugger_sp = *pos; 1114 break; 1115 } 1116 } 1117 } 1118 return debugger_sp; 1119 } 1120 1121 #if 0 1122 static void 1123 TestPromptFormats (StackFrame *frame) 1124 { 1125 if (frame == nullptr) 1126 return; 1127 1128 StreamString s; 1129 const char *prompt_format = 1130 "{addr = '${addr}'\n}" 1131 "{addr-file-or-load = '${addr-file-or-load}'\n}" 1132 "{current-pc-arrow = '${current-pc-arrow}'\n}" 1133 "{process.id = '${process.id}'\n}" 1134 "{process.name = '${process.name}'\n}" 1135 "{process.file.basename = '${process.file.basename}'\n}" 1136 "{process.file.fullpath = '${process.file.fullpath}'\n}" 1137 "{thread.id = '${thread.id}'\n}" 1138 "{thread.index = '${thread.index}'\n}" 1139 "{thread.name = '${thread.name}'\n}" 1140 "{thread.queue = '${thread.queue}'\n}" 1141 "{thread.stop-reason = '${thread.stop-reason}'\n}" 1142 "{target.arch = '${target.arch}'\n}" 1143 "{module.file.basename = '${module.file.basename}'\n}" 1144 "{module.file.fullpath = '${module.file.fullpath}'\n}" 1145 "{file.basename = '${file.basename}'\n}" 1146 "{file.fullpath = '${file.fullpath}'\n}" 1147 "{frame.index = '${frame.index}'\n}" 1148 "{frame.pc = '${frame.pc}'\n}" 1149 "{frame.sp = '${frame.sp}'\n}" 1150 "{frame.fp = '${frame.fp}'\n}" 1151 "{frame.flags = '${frame.flags}'\n}" 1152 "{frame.reg.rdi = '${frame.reg.rdi}'\n}" 1153 "{frame.reg.rip = '${frame.reg.rip}'\n}" 1154 "{frame.reg.rsp = '${frame.reg.rsp}'\n}" 1155 "{frame.reg.rbp = '${frame.reg.rbp}'\n}" 1156 "{frame.reg.rflags = '${frame.reg.rflags}'\n}" 1157 "{frame.reg.xmm0 = '${frame.reg.xmm0}'\n}" 1158 "{frame.reg.carp = '${frame.reg.carp}'\n}" 1159 "{function.id = '${function.id}'\n}" 1160 "{function.changed = '${function.changed}'\n}" 1161 "{function.initial-function = '${function.initial-function}'\n}" 1162 "{function.name = '${function.name}'\n}" 1163 "{function.name-without-args = '${function.name-without-args}'\n}" 1164 "{function.name-with-args = '${function.name-with-args}'\n}" 1165 "{function.addr-offset = '${function.addr-offset}'\n}" 1166 "{function.concrete-only-addr-offset-no-padding = '${function.concrete-only-addr-offset-no-padding}'\n}" 1167 "{function.line-offset = '${function.line-offset}'\n}" 1168 "{function.pc-offset = '${function.pc-offset}'\n}" 1169 "{line.file.basename = '${line.file.basename}'\n}" 1170 "{line.file.fullpath = '${line.file.fullpath}'\n}" 1171 "{line.number = '${line.number}'\n}" 1172 "{line.start-addr = '${line.start-addr}'\n}" 1173 "{line.end-addr = '${line.end-addr}'\n}" 1174 ; 1175 1176 SymbolContext sc (frame->GetSymbolContext(eSymbolContextEverything)); 1177 ExecutionContext exe_ctx; 1178 frame->CalculateExecutionContext(exe_ctx); 1179 if (Debugger::FormatPrompt (prompt_format, &sc, &exe_ctx, &sc.line_entry.range.GetBaseAddress(), s)) 1180 { 1181 printf("%s\n", s.GetData()); 1182 } 1183 else 1184 { 1185 printf ("what we got: %s\n", s.GetData()); 1186 } 1187 } 1188 #endif 1189 1190 bool Debugger::FormatDisassemblerAddress(const FormatEntity::Entry *format, 1191 const SymbolContext *sc, 1192 const SymbolContext *prev_sc, 1193 const ExecutionContext *exe_ctx, 1194 const Address *addr, Stream &s) { 1195 FormatEntity::Entry format_entry; 1196 1197 if (format == nullptr) { 1198 if (exe_ctx != nullptr && exe_ctx->HasTargetScope()) 1199 format = exe_ctx->GetTargetRef().GetDebugger().GetDisassemblyFormat(); 1200 if (format == nullptr) { 1201 FormatEntity::Parse("${addr}: ", format_entry); 1202 format = &format_entry; 1203 } 1204 } 1205 bool function_changed = false; 1206 bool initial_function = false; 1207 if (prev_sc && (prev_sc->function || prev_sc->symbol)) { 1208 if (sc && (sc->function || sc->symbol)) { 1209 if (prev_sc->symbol && sc->symbol) { 1210 if (!sc->symbol->Compare(prev_sc->symbol->GetName(), 1211 prev_sc->symbol->GetType())) { 1212 function_changed = true; 1213 } 1214 } else if (prev_sc->function && sc->function) { 1215 if (prev_sc->function->GetMangled() != sc->function->GetMangled()) { 1216 function_changed = true; 1217 } 1218 } 1219 } 1220 } 1221 // The first context on a list of instructions will have a prev_sc that 1222 // has no Function or Symbol -- if SymbolContext had an IsValid() method, it 1223 // would return false. But we do get a prev_sc pointer. 1224 if ((sc && (sc->function || sc->symbol)) && prev_sc && 1225 (prev_sc->function == nullptr && prev_sc->symbol == nullptr)) { 1226 initial_function = true; 1227 } 1228 return FormatEntity::Format(*format, s, sc, exe_ctx, addr, nullptr, 1229 function_changed, initial_function); 1230 } 1231 1232 void Debugger::SetLoggingCallback(lldb::LogOutputCallback log_callback, 1233 void *baton) { 1234 // For simplicity's sake, I am not going to deal with how to close down any 1235 // open logging streams, I just redirect everything from here on out to the 1236 // callback. 1237 m_log_callback_stream_sp.reset(new StreamCallback(log_callback, baton)); 1238 } 1239 1240 bool Debugger::EnableLog(const char *channel, const char **categories, 1241 const char *log_file, uint32_t log_options, 1242 Stream &error_stream) { 1243 StreamSP log_stream_sp; 1244 if (m_log_callback_stream_sp) { 1245 log_stream_sp = m_log_callback_stream_sp; 1246 // For now when using the callback mode you always get thread & timestamp. 1247 log_options |= 1248 LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_THREAD_NAME; 1249 } else if (log_file == nullptr || *log_file == '\0') { 1250 log_stream_sp = GetOutputFile(); 1251 } else { 1252 LogStreamMap::iterator pos = m_log_streams.find(log_file); 1253 if (pos != m_log_streams.end()) 1254 log_stream_sp = pos->second.lock(); 1255 if (!log_stream_sp) { 1256 uint32_t options = File::eOpenOptionWrite | File::eOpenOptionCanCreate | 1257 File::eOpenOptionCloseOnExec | File::eOpenOptionAppend; 1258 if (!(log_options & LLDB_LOG_OPTION_APPEND)) 1259 options |= File::eOpenOptionTruncate; 1260 1261 log_stream_sp.reset(new StreamFile(log_file, options)); 1262 m_log_streams[log_file] = log_stream_sp; 1263 } 1264 } 1265 assert(log_stream_sp); 1266 1267 if (log_options == 0) 1268 log_options = 1269 LLDB_LOG_OPTION_PREPEND_THREAD_NAME | LLDB_LOG_OPTION_THREADSAFE; 1270 1271 return Log::EnableLogChannel(log_stream_sp, log_options, channel, categories, 1272 error_stream); 1273 } 1274 1275 SourceManager &Debugger::GetSourceManager() { 1276 if (!m_source_manager_ap) 1277 m_source_manager_ap.reset(new SourceManager(shared_from_this())); 1278 return *m_source_manager_ap; 1279 } 1280 1281 // This function handles events that were broadcast by the process. 1282 void Debugger::HandleBreakpointEvent(const EventSP &event_sp) { 1283 using namespace lldb; 1284 const uint32_t event_type = 1285 Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent( 1286 event_sp); 1287 1288 // if (event_type & eBreakpointEventTypeAdded 1289 // || event_type & eBreakpointEventTypeRemoved 1290 // || event_type & eBreakpointEventTypeEnabled 1291 // || event_type & eBreakpointEventTypeDisabled 1292 // || event_type & eBreakpointEventTypeCommandChanged 1293 // || event_type & eBreakpointEventTypeConditionChanged 1294 // || event_type & eBreakpointEventTypeIgnoreChanged 1295 // || event_type & eBreakpointEventTypeLocationsResolved) 1296 // { 1297 // // Don't do anything about these events, since the breakpoint 1298 // commands already echo these actions. 1299 // } 1300 // 1301 if (event_type & eBreakpointEventTypeLocationsAdded) { 1302 uint32_t num_new_locations = 1303 Breakpoint::BreakpointEventData::GetNumBreakpointLocationsFromEvent( 1304 event_sp); 1305 if (num_new_locations > 0) { 1306 BreakpointSP breakpoint = 1307 Breakpoint::BreakpointEventData::GetBreakpointFromEvent(event_sp); 1308 StreamSP output_sp(GetAsyncOutputStream()); 1309 if (output_sp) { 1310 output_sp->Printf("%d location%s added to breakpoint %d\n", 1311 num_new_locations, num_new_locations == 1 ? "" : "s", 1312 breakpoint->GetID()); 1313 output_sp->Flush(); 1314 } 1315 } 1316 } 1317 // else if (event_type & eBreakpointEventTypeLocationsRemoved) 1318 // { 1319 // // These locations just get disabled, not sure it is worth spamming 1320 // folks about this on the command line. 1321 // } 1322 // else if (event_type & eBreakpointEventTypeLocationsResolved) 1323 // { 1324 // // This might be an interesting thing to note, but I'm going to 1325 // leave it quiet for now, it just looked noisy. 1326 // } 1327 } 1328 1329 size_t Debugger::GetProcessSTDOUT(Process *process, Stream *stream) { 1330 size_t total_bytes = 0; 1331 if (stream == nullptr) 1332 stream = GetOutputFile().get(); 1333 1334 if (stream) { 1335 // The process has stuff waiting for stdout; get it and write it out to the 1336 // appropriate place. 1337 if (process == nullptr) { 1338 TargetSP target_sp = GetTargetList().GetSelectedTarget(); 1339 if (target_sp) 1340 process = target_sp->GetProcessSP().get(); 1341 } 1342 if (process) { 1343 Error error; 1344 size_t len; 1345 char stdio_buffer[1024]; 1346 while ((len = process->GetSTDOUT(stdio_buffer, sizeof(stdio_buffer), 1347 error)) > 0) { 1348 stream->Write(stdio_buffer, len); 1349 total_bytes += len; 1350 } 1351 } 1352 stream->Flush(); 1353 } 1354 return total_bytes; 1355 } 1356 1357 size_t Debugger::GetProcessSTDERR(Process *process, Stream *stream) { 1358 size_t total_bytes = 0; 1359 if (stream == nullptr) 1360 stream = GetOutputFile().get(); 1361 1362 if (stream) { 1363 // The process has stuff waiting for stderr; get it and write it out to the 1364 // appropriate place. 1365 if (process == nullptr) { 1366 TargetSP target_sp = GetTargetList().GetSelectedTarget(); 1367 if (target_sp) 1368 process = target_sp->GetProcessSP().get(); 1369 } 1370 if (process) { 1371 Error error; 1372 size_t len; 1373 char stdio_buffer[1024]; 1374 while ((len = process->GetSTDERR(stdio_buffer, sizeof(stdio_buffer), 1375 error)) > 0) { 1376 stream->Write(stdio_buffer, len); 1377 total_bytes += len; 1378 } 1379 } 1380 stream->Flush(); 1381 } 1382 return total_bytes; 1383 } 1384 1385 // This function handles events that were broadcast by the process. 1386 void Debugger::HandleProcessEvent(const EventSP &event_sp) { 1387 using namespace lldb; 1388 const uint32_t event_type = event_sp->GetType(); 1389 ProcessSP process_sp = 1390 (event_type == Process::eBroadcastBitStructuredData) 1391 ? EventDataStructuredData::GetProcessFromEvent(event_sp.get()) 1392 : Process::ProcessEventData::GetProcessFromEvent(event_sp.get()); 1393 1394 StreamSP output_stream_sp = GetAsyncOutputStream(); 1395 StreamSP error_stream_sp = GetAsyncErrorStream(); 1396 const bool gui_enabled = IsForwardingEvents(); 1397 1398 if (!gui_enabled) { 1399 bool pop_process_io_handler = false; 1400 assert(process_sp); 1401 1402 bool state_is_stopped = false; 1403 const bool got_state_changed = 1404 (event_type & Process::eBroadcastBitStateChanged) != 0; 1405 const bool got_stdout = (event_type & Process::eBroadcastBitSTDOUT) != 0; 1406 const bool got_stderr = (event_type & Process::eBroadcastBitSTDERR) != 0; 1407 const bool got_structured_data = 1408 (event_type & Process::eBroadcastBitStructuredData) != 0; 1409 1410 if (got_state_changed) { 1411 StateType event_state = 1412 Process::ProcessEventData::GetStateFromEvent(event_sp.get()); 1413 state_is_stopped = StateIsStoppedState(event_state, false); 1414 } 1415 1416 // Display running state changes first before any STDIO 1417 if (got_state_changed && !state_is_stopped) { 1418 Process::HandleProcessStateChangedEvent(event_sp, output_stream_sp.get(), 1419 pop_process_io_handler); 1420 } 1421 1422 // Now display and STDOUT 1423 if (got_stdout || got_state_changed) { 1424 GetProcessSTDOUT(process_sp.get(), output_stream_sp.get()); 1425 } 1426 1427 // Now display and STDERR 1428 if (got_stderr || got_state_changed) { 1429 GetProcessSTDERR(process_sp.get(), error_stream_sp.get()); 1430 } 1431 1432 // Give structured data events an opportunity to display. 1433 if (got_structured_data) { 1434 StructuredDataPluginSP plugin_sp = 1435 EventDataStructuredData::GetPluginFromEvent(event_sp.get()); 1436 if (plugin_sp) { 1437 auto structured_data_sp = 1438 EventDataStructuredData::GetObjectFromEvent(event_sp.get()); 1439 if (output_stream_sp) { 1440 StreamString content_stream; 1441 Error error = 1442 plugin_sp->GetDescription(structured_data_sp, content_stream); 1443 if (error.Success()) { 1444 if (!content_stream.GetString().empty()) { 1445 // Add newline. 1446 content_stream.PutChar('\n'); 1447 content_stream.Flush(); 1448 1449 // Print it. 1450 output_stream_sp->PutCString(content_stream.GetString()); 1451 } 1452 } else { 1453 error_stream_sp->Printf("Failed to print structured " 1454 "data with plugin %s: %s", 1455 plugin_sp->GetPluginName().AsCString(), 1456 error.AsCString()); 1457 } 1458 } 1459 } 1460 } 1461 1462 // Now display any stopped state changes after any STDIO 1463 if (got_state_changed && state_is_stopped) { 1464 Process::HandleProcessStateChangedEvent(event_sp, output_stream_sp.get(), 1465 pop_process_io_handler); 1466 } 1467 1468 output_stream_sp->Flush(); 1469 error_stream_sp->Flush(); 1470 1471 if (pop_process_io_handler) 1472 process_sp->PopProcessIOHandler(); 1473 } 1474 } 1475 1476 void Debugger::HandleThreadEvent(const EventSP &event_sp) { 1477 // At present the only thread event we handle is the Frame Changed event, 1478 // and all we do for that is just reprint the thread status for that thread. 1479 using namespace lldb; 1480 const uint32_t event_type = event_sp->GetType(); 1481 const bool stop_format = true; 1482 if (event_type == Thread::eBroadcastBitStackChanged || 1483 event_type == Thread::eBroadcastBitThreadSelected) { 1484 ThreadSP thread_sp( 1485 Thread::ThreadEventData::GetThreadFromEvent(event_sp.get())); 1486 if (thread_sp) { 1487 thread_sp->GetStatus(*GetAsyncOutputStream(), 0, 1, 1, stop_format); 1488 } 1489 } 1490 } 1491 1492 bool Debugger::IsForwardingEvents() { return (bool)m_forward_listener_sp; } 1493 1494 void Debugger::EnableForwardEvents(const ListenerSP &listener_sp) { 1495 m_forward_listener_sp = listener_sp; 1496 } 1497 1498 void Debugger::CancelForwardEvents(const ListenerSP &listener_sp) { 1499 m_forward_listener_sp.reset(); 1500 } 1501 1502 void Debugger::DefaultEventHandler() { 1503 ListenerSP listener_sp(GetListener()); 1504 ConstString broadcaster_class_target(Target::GetStaticBroadcasterClass()); 1505 ConstString broadcaster_class_process(Process::GetStaticBroadcasterClass()); 1506 ConstString broadcaster_class_thread(Thread::GetStaticBroadcasterClass()); 1507 BroadcastEventSpec target_event_spec(broadcaster_class_target, 1508 Target::eBroadcastBitBreakpointChanged); 1509 1510 BroadcastEventSpec process_event_spec( 1511 broadcaster_class_process, 1512 Process::eBroadcastBitStateChanged | Process::eBroadcastBitSTDOUT | 1513 Process::eBroadcastBitSTDERR | Process::eBroadcastBitStructuredData); 1514 1515 BroadcastEventSpec thread_event_spec(broadcaster_class_thread, 1516 Thread::eBroadcastBitStackChanged | 1517 Thread::eBroadcastBitThreadSelected); 1518 1519 listener_sp->StartListeningForEventSpec(m_broadcaster_manager_sp, 1520 target_event_spec); 1521 listener_sp->StartListeningForEventSpec(m_broadcaster_manager_sp, 1522 process_event_spec); 1523 listener_sp->StartListeningForEventSpec(m_broadcaster_manager_sp, 1524 thread_event_spec); 1525 listener_sp->StartListeningForEvents( 1526 m_command_interpreter_ap.get(), 1527 CommandInterpreter::eBroadcastBitQuitCommandReceived | 1528 CommandInterpreter::eBroadcastBitAsynchronousOutputData | 1529 CommandInterpreter::eBroadcastBitAsynchronousErrorData); 1530 1531 // Let the thread that spawned us know that we have started up and 1532 // that we are now listening to all required events so no events get missed 1533 m_sync_broadcaster.BroadcastEvent(eBroadcastBitEventThreadIsListening); 1534 1535 bool done = false; 1536 while (!done) { 1537 EventSP event_sp; 1538 if (listener_sp->GetEvent(event_sp, llvm::None)) { 1539 if (event_sp) { 1540 Broadcaster *broadcaster = event_sp->GetBroadcaster(); 1541 if (broadcaster) { 1542 uint32_t event_type = event_sp->GetType(); 1543 ConstString broadcaster_class(broadcaster->GetBroadcasterClass()); 1544 if (broadcaster_class == broadcaster_class_process) { 1545 HandleProcessEvent(event_sp); 1546 } else if (broadcaster_class == broadcaster_class_target) { 1547 if (Breakpoint::BreakpointEventData::GetEventDataFromEvent( 1548 event_sp.get())) { 1549 HandleBreakpointEvent(event_sp); 1550 } 1551 } else if (broadcaster_class == broadcaster_class_thread) { 1552 HandleThreadEvent(event_sp); 1553 } else if (broadcaster == m_command_interpreter_ap.get()) { 1554 if (event_type & 1555 CommandInterpreter::eBroadcastBitQuitCommandReceived) { 1556 done = true; 1557 } else if (event_type & 1558 CommandInterpreter::eBroadcastBitAsynchronousErrorData) { 1559 const char *data = reinterpret_cast<const char *>( 1560 EventDataBytes::GetBytesFromEvent(event_sp.get())); 1561 if (data && data[0]) { 1562 StreamSP error_sp(GetAsyncErrorStream()); 1563 if (error_sp) { 1564 error_sp->PutCString(data); 1565 error_sp->Flush(); 1566 } 1567 } 1568 } else if (event_type & CommandInterpreter:: 1569 eBroadcastBitAsynchronousOutputData) { 1570 const char *data = reinterpret_cast<const char *>( 1571 EventDataBytes::GetBytesFromEvent(event_sp.get())); 1572 if (data && data[0]) { 1573 StreamSP output_sp(GetAsyncOutputStream()); 1574 if (output_sp) { 1575 output_sp->PutCString(data); 1576 output_sp->Flush(); 1577 } 1578 } 1579 } 1580 } 1581 } 1582 1583 if (m_forward_listener_sp) 1584 m_forward_listener_sp->AddEvent(event_sp); 1585 } 1586 } 1587 } 1588 } 1589 1590 lldb::thread_result_t Debugger::EventHandlerThread(lldb::thread_arg_t arg) { 1591 ((Debugger *)arg)->DefaultEventHandler(); 1592 return NULL; 1593 } 1594 1595 bool Debugger::StartEventHandlerThread() { 1596 if (!m_event_handler_thread.IsJoinable()) { 1597 // We must synchronize with the DefaultEventHandler() thread to ensure 1598 // it is up and running and listening to events before we return from 1599 // this function. We do this by listening to events for the 1600 // eBroadcastBitEventThreadIsListening from the m_sync_broadcaster 1601 ListenerSP listener_sp( 1602 Listener::MakeListener("lldb.debugger.event-handler")); 1603 listener_sp->StartListeningForEvents(&m_sync_broadcaster, 1604 eBroadcastBitEventThreadIsListening); 1605 1606 // Use larger 8MB stack for this thread 1607 m_event_handler_thread = ThreadLauncher::LaunchThread( 1608 "lldb.debugger.event-handler", EventHandlerThread, this, nullptr, 1609 g_debugger_event_thread_stack_bytes); 1610 1611 // Make sure DefaultEventHandler() is running and listening to events before 1612 // we return 1613 // from this function. We are only listening for events of type 1614 // eBroadcastBitEventThreadIsListening so we don't need to check the event, 1615 // we just need 1616 // to wait an infinite amount of time for it (nullptr timeout as the first 1617 // parameter) 1618 lldb::EventSP event_sp; 1619 listener_sp->GetEvent(event_sp, llvm::None); 1620 } 1621 return m_event_handler_thread.IsJoinable(); 1622 } 1623 1624 void Debugger::StopEventHandlerThread() { 1625 if (m_event_handler_thread.IsJoinable()) { 1626 GetCommandInterpreter().BroadcastEvent( 1627 CommandInterpreter::eBroadcastBitQuitCommandReceived); 1628 m_event_handler_thread.Join(nullptr); 1629 } 1630 } 1631 1632 lldb::thread_result_t Debugger::IOHandlerThread(lldb::thread_arg_t arg) { 1633 Debugger *debugger = (Debugger *)arg; 1634 debugger->ExecuteIOHandlers(); 1635 debugger->StopEventHandlerThread(); 1636 return NULL; 1637 } 1638 1639 bool Debugger::HasIOHandlerThread() { return m_io_handler_thread.IsJoinable(); } 1640 1641 bool Debugger::StartIOHandlerThread() { 1642 if (!m_io_handler_thread.IsJoinable()) 1643 m_io_handler_thread = ThreadLauncher::LaunchThread( 1644 "lldb.debugger.io-handler", IOHandlerThread, this, nullptr, 1645 8 * 1024 * 1024); // Use larger 8MB stack for this thread 1646 return m_io_handler_thread.IsJoinable(); 1647 } 1648 1649 void Debugger::StopIOHandlerThread() { 1650 if (m_io_handler_thread.IsJoinable()) { 1651 if (m_input_file_sp) 1652 m_input_file_sp->GetFile().Close(); 1653 m_io_handler_thread.Join(nullptr); 1654 } 1655 } 1656 1657 void Debugger::JoinIOHandlerThread() { 1658 if (HasIOHandlerThread()) { 1659 thread_result_t result; 1660 m_io_handler_thread.Join(&result); 1661 m_io_handler_thread = LLDB_INVALID_HOST_THREAD; 1662 } 1663 } 1664 1665 Target *Debugger::GetDummyTarget() { 1666 return m_target_list.GetDummyTarget(*this).get(); 1667 } 1668 1669 Target *Debugger::GetSelectedOrDummyTarget(bool prefer_dummy) { 1670 Target *target = nullptr; 1671 if (!prefer_dummy) { 1672 target = m_target_list.GetSelectedTarget().get(); 1673 if (target) 1674 return target; 1675 } 1676 1677 return GetDummyTarget(); 1678 } 1679 1680 Error Debugger::RunREPL(LanguageType language, const char *repl_options) { 1681 Error err; 1682 FileSpec repl_executable; 1683 1684 if (language == eLanguageTypeUnknown) { 1685 std::set<LanguageType> repl_languages; 1686 1687 Language::GetLanguagesSupportingREPLs(repl_languages); 1688 1689 if (repl_languages.size() == 1) { 1690 language = *repl_languages.begin(); 1691 } else if (repl_languages.empty()) { 1692 err.SetErrorStringWithFormat( 1693 "LLDB isn't configured with REPL support for any languages."); 1694 return err; 1695 } else { 1696 err.SetErrorStringWithFormat( 1697 "Multiple possible REPL languages. Please specify a language."); 1698 return err; 1699 } 1700 } 1701 1702 Target *const target = 1703 nullptr; // passing in an empty target means the REPL must create one 1704 1705 REPLSP repl_sp(REPL::Create(err, language, this, target, repl_options)); 1706 1707 if (!err.Success()) { 1708 return err; 1709 } 1710 1711 if (!repl_sp) { 1712 err.SetErrorStringWithFormat("couldn't find a REPL for %s", 1713 Language::GetNameForLanguageType(language)); 1714 return err; 1715 } 1716 1717 repl_sp->SetCompilerOptions(repl_options); 1718 repl_sp->RunLoop(); 1719 1720 return err; 1721 } 1722