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