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