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