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/StreamFile.h" 32 #include "lldb/Core/StructuredData.h" 33 #include "lldb/Core/Timer.h" 34 #include "lldb/Core/ValueObject.h" 35 #include "lldb/Core/ValueObjectVariable.h" 36 #include "lldb/DataFormatters/DataVisualization.h" 37 #include "lldb/DataFormatters/FormatManager.h" 38 #include "lldb/DataFormatters/TypeSummary.h" 39 #include "lldb/Expression/REPL.h" 40 #include "lldb/Host/ConnectionFileDescriptor.h" 41 #include "lldb/Host/HostInfo.h" 42 #include "lldb/Host/Terminal.h" 43 #include "lldb/Host/ThreadLauncher.h" 44 #include "lldb/Interpreter/CommandInterpreter.h" 45 #include "lldb/Interpreter/OptionValueProperties.h" 46 #include "lldb/Interpreter/OptionValueSInt64.h" 47 #include "lldb/Interpreter/OptionValueString.h" 48 #include "lldb/Symbol/CompileUnit.h" 49 #include "lldb/Symbol/Function.h" 50 #include "lldb/Symbol/Symbol.h" 51 #include "lldb/Symbol/VariableList.h" 52 #include "lldb/Target/Language.h" 53 #include "lldb/Target/Process.h" 54 #include "lldb/Target/RegisterContext.h" 55 #include "lldb/Target/SectionLoadList.h" 56 #include "lldb/Target/StopInfo.h" 57 #include "lldb/Target/StructuredDataPlugin.h" 58 #include "lldb/Target/Target.h" 59 #include "lldb/Target/TargetList.h" 60 #include "lldb/Target/Thread.h" 61 #include "lldb/Utility/AnsiTerminal.h" 62 #include "lldb/Utility/StreamCallback.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, llvm::sys::fs::file_type ft, 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 namespace fs = llvm::sys::fs; 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 (ft == fs::file_type::regular_file || ft == fs::file_type::symlink_file || 578 ft == fs::file_type::type_unknown) { 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 (ft == fs::file_type::directory_file || 592 ft == fs::file_type::symlink_file || 593 ft == fs::file_type::type_unknown) { 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(llvm::StringRef channel, 1243 llvm::ArrayRef<const char *> categories, 1244 llvm::StringRef log_file, uint32_t log_options, 1245 llvm::raw_ostream &error_stream) { 1246 const bool should_close = true; 1247 const bool unbuffered = true; 1248 1249 std::shared_ptr<llvm::raw_ostream> log_stream_sp; 1250 if (m_log_callback_stream_sp) { 1251 log_stream_sp = m_log_callback_stream_sp; 1252 // For now when using the callback mode you always get thread & timestamp. 1253 log_options |= 1254 LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_THREAD_NAME; 1255 } else if (log_file.empty()) { 1256 log_stream_sp = std::make_shared<llvm::raw_fd_ostream>( 1257 GetOutputFile()->GetFile().GetDescriptor(), !should_close, unbuffered); 1258 } else { 1259 auto pos = m_log_streams.find(log_file); 1260 if (pos != m_log_streams.end()) 1261 log_stream_sp = pos->second.lock(); 1262 if (!log_stream_sp) { 1263 llvm::sys::fs::OpenFlags flags = llvm::sys::fs::F_Text; 1264 if (log_options & LLDB_LOG_OPTION_APPEND) 1265 flags |= llvm::sys::fs::F_Append; 1266 int FD; 1267 if (std::error_code ec = 1268 llvm::sys::fs::openFileForWrite(log_file, FD, flags)) { 1269 error_stream << "Unable to open log file: " << ec.message(); 1270 return false; 1271 } 1272 log_stream_sp.reset( 1273 new llvm::raw_fd_ostream(FD, should_close, unbuffered)); 1274 m_log_streams[log_file] = log_stream_sp; 1275 } 1276 } 1277 assert(log_stream_sp); 1278 1279 if (log_options == 0) 1280 log_options = 1281 LLDB_LOG_OPTION_PREPEND_THREAD_NAME | LLDB_LOG_OPTION_THREADSAFE; 1282 1283 return Log::EnableLogChannel(log_stream_sp, log_options, channel, categories, 1284 error_stream); 1285 } 1286 1287 SourceManager &Debugger::GetSourceManager() { 1288 if (!m_source_manager_ap) 1289 m_source_manager_ap.reset(new SourceManager(shared_from_this())); 1290 return *m_source_manager_ap; 1291 } 1292 1293 // This function handles events that were broadcast by the process. 1294 void Debugger::HandleBreakpointEvent(const EventSP &event_sp) { 1295 using namespace lldb; 1296 const uint32_t event_type = 1297 Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent( 1298 event_sp); 1299 1300 // if (event_type & eBreakpointEventTypeAdded 1301 // || event_type & eBreakpointEventTypeRemoved 1302 // || event_type & eBreakpointEventTypeEnabled 1303 // || event_type & eBreakpointEventTypeDisabled 1304 // || event_type & eBreakpointEventTypeCommandChanged 1305 // || event_type & eBreakpointEventTypeConditionChanged 1306 // || event_type & eBreakpointEventTypeIgnoreChanged 1307 // || event_type & eBreakpointEventTypeLocationsResolved) 1308 // { 1309 // // Don't do anything about these events, since the breakpoint 1310 // commands already echo these actions. 1311 // } 1312 // 1313 if (event_type & eBreakpointEventTypeLocationsAdded) { 1314 uint32_t num_new_locations = 1315 Breakpoint::BreakpointEventData::GetNumBreakpointLocationsFromEvent( 1316 event_sp); 1317 if (num_new_locations > 0) { 1318 BreakpointSP breakpoint = 1319 Breakpoint::BreakpointEventData::GetBreakpointFromEvent(event_sp); 1320 StreamSP output_sp(GetAsyncOutputStream()); 1321 if (output_sp) { 1322 output_sp->Printf("%d location%s added to breakpoint %d\n", 1323 num_new_locations, num_new_locations == 1 ? "" : "s", 1324 breakpoint->GetID()); 1325 output_sp->Flush(); 1326 } 1327 } 1328 } 1329 // else if (event_type & eBreakpointEventTypeLocationsRemoved) 1330 // { 1331 // // These locations just get disabled, not sure it is worth spamming 1332 // folks about this on the command line. 1333 // } 1334 // else if (event_type & eBreakpointEventTypeLocationsResolved) 1335 // { 1336 // // This might be an interesting thing to note, but I'm going to 1337 // leave it quiet for now, it just looked noisy. 1338 // } 1339 } 1340 1341 size_t Debugger::GetProcessSTDOUT(Process *process, Stream *stream) { 1342 size_t total_bytes = 0; 1343 if (stream == nullptr) 1344 stream = GetOutputFile().get(); 1345 1346 if (stream) { 1347 // The process has stuff waiting for stdout; get it and write it out to the 1348 // appropriate place. 1349 if (process == nullptr) { 1350 TargetSP target_sp = GetTargetList().GetSelectedTarget(); 1351 if (target_sp) 1352 process = target_sp->GetProcessSP().get(); 1353 } 1354 if (process) { 1355 Error error; 1356 size_t len; 1357 char stdio_buffer[1024]; 1358 while ((len = process->GetSTDOUT(stdio_buffer, sizeof(stdio_buffer), 1359 error)) > 0) { 1360 stream->Write(stdio_buffer, len); 1361 total_bytes += len; 1362 } 1363 } 1364 stream->Flush(); 1365 } 1366 return total_bytes; 1367 } 1368 1369 size_t Debugger::GetProcessSTDERR(Process *process, Stream *stream) { 1370 size_t total_bytes = 0; 1371 if (stream == nullptr) 1372 stream = GetOutputFile().get(); 1373 1374 if (stream) { 1375 // The process has stuff waiting for stderr; get it and write it out to the 1376 // appropriate place. 1377 if (process == nullptr) { 1378 TargetSP target_sp = GetTargetList().GetSelectedTarget(); 1379 if (target_sp) 1380 process = target_sp->GetProcessSP().get(); 1381 } 1382 if (process) { 1383 Error error; 1384 size_t len; 1385 char stdio_buffer[1024]; 1386 while ((len = process->GetSTDERR(stdio_buffer, sizeof(stdio_buffer), 1387 error)) > 0) { 1388 stream->Write(stdio_buffer, len); 1389 total_bytes += len; 1390 } 1391 } 1392 stream->Flush(); 1393 } 1394 return total_bytes; 1395 } 1396 1397 // This function handles events that were broadcast by the process. 1398 void Debugger::HandleProcessEvent(const EventSP &event_sp) { 1399 using namespace lldb; 1400 const uint32_t event_type = event_sp->GetType(); 1401 ProcessSP process_sp = 1402 (event_type == Process::eBroadcastBitStructuredData) 1403 ? EventDataStructuredData::GetProcessFromEvent(event_sp.get()) 1404 : Process::ProcessEventData::GetProcessFromEvent(event_sp.get()); 1405 1406 StreamSP output_stream_sp = GetAsyncOutputStream(); 1407 StreamSP error_stream_sp = GetAsyncErrorStream(); 1408 const bool gui_enabled = IsForwardingEvents(); 1409 1410 if (!gui_enabled) { 1411 bool pop_process_io_handler = false; 1412 assert(process_sp); 1413 1414 bool state_is_stopped = false; 1415 const bool got_state_changed = 1416 (event_type & Process::eBroadcastBitStateChanged) != 0; 1417 const bool got_stdout = (event_type & Process::eBroadcastBitSTDOUT) != 0; 1418 const bool got_stderr = (event_type & Process::eBroadcastBitSTDERR) != 0; 1419 const bool got_structured_data = 1420 (event_type & Process::eBroadcastBitStructuredData) != 0; 1421 1422 if (got_state_changed) { 1423 StateType event_state = 1424 Process::ProcessEventData::GetStateFromEvent(event_sp.get()); 1425 state_is_stopped = StateIsStoppedState(event_state, false); 1426 } 1427 1428 // Display running state changes first before any STDIO 1429 if (got_state_changed && !state_is_stopped) { 1430 Process::HandleProcessStateChangedEvent(event_sp, output_stream_sp.get(), 1431 pop_process_io_handler); 1432 } 1433 1434 // Now display and STDOUT 1435 if (got_stdout || got_state_changed) { 1436 GetProcessSTDOUT(process_sp.get(), output_stream_sp.get()); 1437 } 1438 1439 // Now display and STDERR 1440 if (got_stderr || got_state_changed) { 1441 GetProcessSTDERR(process_sp.get(), error_stream_sp.get()); 1442 } 1443 1444 // Give structured data events an opportunity to display. 1445 if (got_structured_data) { 1446 StructuredDataPluginSP plugin_sp = 1447 EventDataStructuredData::GetPluginFromEvent(event_sp.get()); 1448 if (plugin_sp) { 1449 auto structured_data_sp = 1450 EventDataStructuredData::GetObjectFromEvent(event_sp.get()); 1451 if (output_stream_sp) { 1452 StreamString content_stream; 1453 Error error = 1454 plugin_sp->GetDescription(structured_data_sp, content_stream); 1455 if (error.Success()) { 1456 if (!content_stream.GetString().empty()) { 1457 // Add newline. 1458 content_stream.PutChar('\n'); 1459 content_stream.Flush(); 1460 1461 // Print it. 1462 output_stream_sp->PutCString(content_stream.GetString()); 1463 } 1464 } else { 1465 error_stream_sp->Printf("Failed to print structured " 1466 "data with plugin %s: %s", 1467 plugin_sp->GetPluginName().AsCString(), 1468 error.AsCString()); 1469 } 1470 } 1471 } 1472 } 1473 1474 // Now display any stopped state changes after any STDIO 1475 if (got_state_changed && state_is_stopped) { 1476 Process::HandleProcessStateChangedEvent(event_sp, output_stream_sp.get(), 1477 pop_process_io_handler); 1478 } 1479 1480 output_stream_sp->Flush(); 1481 error_stream_sp->Flush(); 1482 1483 if (pop_process_io_handler) 1484 process_sp->PopProcessIOHandler(); 1485 } 1486 } 1487 1488 void Debugger::HandleThreadEvent(const EventSP &event_sp) { 1489 // At present the only thread event we handle is the Frame Changed event, 1490 // and all we do for that is just reprint the thread status for that thread. 1491 using namespace lldb; 1492 const uint32_t event_type = event_sp->GetType(); 1493 const bool stop_format = true; 1494 if (event_type == Thread::eBroadcastBitStackChanged || 1495 event_type == Thread::eBroadcastBitThreadSelected) { 1496 ThreadSP thread_sp( 1497 Thread::ThreadEventData::GetThreadFromEvent(event_sp.get())); 1498 if (thread_sp) { 1499 thread_sp->GetStatus(*GetAsyncOutputStream(), 0, 1, 1, stop_format); 1500 } 1501 } 1502 } 1503 1504 bool Debugger::IsForwardingEvents() { return (bool)m_forward_listener_sp; } 1505 1506 void Debugger::EnableForwardEvents(const ListenerSP &listener_sp) { 1507 m_forward_listener_sp = listener_sp; 1508 } 1509 1510 void Debugger::CancelForwardEvents(const ListenerSP &listener_sp) { 1511 m_forward_listener_sp.reset(); 1512 } 1513 1514 void Debugger::DefaultEventHandler() { 1515 ListenerSP listener_sp(GetListener()); 1516 ConstString broadcaster_class_target(Target::GetStaticBroadcasterClass()); 1517 ConstString broadcaster_class_process(Process::GetStaticBroadcasterClass()); 1518 ConstString broadcaster_class_thread(Thread::GetStaticBroadcasterClass()); 1519 BroadcastEventSpec target_event_spec(broadcaster_class_target, 1520 Target::eBroadcastBitBreakpointChanged); 1521 1522 BroadcastEventSpec process_event_spec( 1523 broadcaster_class_process, 1524 Process::eBroadcastBitStateChanged | Process::eBroadcastBitSTDOUT | 1525 Process::eBroadcastBitSTDERR | Process::eBroadcastBitStructuredData); 1526 1527 BroadcastEventSpec thread_event_spec(broadcaster_class_thread, 1528 Thread::eBroadcastBitStackChanged | 1529 Thread::eBroadcastBitThreadSelected); 1530 1531 listener_sp->StartListeningForEventSpec(m_broadcaster_manager_sp, 1532 target_event_spec); 1533 listener_sp->StartListeningForEventSpec(m_broadcaster_manager_sp, 1534 process_event_spec); 1535 listener_sp->StartListeningForEventSpec(m_broadcaster_manager_sp, 1536 thread_event_spec); 1537 listener_sp->StartListeningForEvents( 1538 m_command_interpreter_ap.get(), 1539 CommandInterpreter::eBroadcastBitQuitCommandReceived | 1540 CommandInterpreter::eBroadcastBitAsynchronousOutputData | 1541 CommandInterpreter::eBroadcastBitAsynchronousErrorData); 1542 1543 // Let the thread that spawned us know that we have started up and 1544 // that we are now listening to all required events so no events get missed 1545 m_sync_broadcaster.BroadcastEvent(eBroadcastBitEventThreadIsListening); 1546 1547 bool done = false; 1548 while (!done) { 1549 EventSP event_sp; 1550 if (listener_sp->GetEvent(event_sp, llvm::None)) { 1551 if (event_sp) { 1552 Broadcaster *broadcaster = event_sp->GetBroadcaster(); 1553 if (broadcaster) { 1554 uint32_t event_type = event_sp->GetType(); 1555 ConstString broadcaster_class(broadcaster->GetBroadcasterClass()); 1556 if (broadcaster_class == broadcaster_class_process) { 1557 HandleProcessEvent(event_sp); 1558 } else if (broadcaster_class == broadcaster_class_target) { 1559 if (Breakpoint::BreakpointEventData::GetEventDataFromEvent( 1560 event_sp.get())) { 1561 HandleBreakpointEvent(event_sp); 1562 } 1563 } else if (broadcaster_class == broadcaster_class_thread) { 1564 HandleThreadEvent(event_sp); 1565 } else if (broadcaster == m_command_interpreter_ap.get()) { 1566 if (event_type & 1567 CommandInterpreter::eBroadcastBitQuitCommandReceived) { 1568 done = true; 1569 } else if (event_type & 1570 CommandInterpreter::eBroadcastBitAsynchronousErrorData) { 1571 const char *data = reinterpret_cast<const char *>( 1572 EventDataBytes::GetBytesFromEvent(event_sp.get())); 1573 if (data && data[0]) { 1574 StreamSP error_sp(GetAsyncErrorStream()); 1575 if (error_sp) { 1576 error_sp->PutCString(data); 1577 error_sp->Flush(); 1578 } 1579 } 1580 } else if (event_type & CommandInterpreter:: 1581 eBroadcastBitAsynchronousOutputData) { 1582 const char *data = reinterpret_cast<const char *>( 1583 EventDataBytes::GetBytesFromEvent(event_sp.get())); 1584 if (data && data[0]) { 1585 StreamSP output_sp(GetAsyncOutputStream()); 1586 if (output_sp) { 1587 output_sp->PutCString(data); 1588 output_sp->Flush(); 1589 } 1590 } 1591 } 1592 } 1593 } 1594 1595 if (m_forward_listener_sp) 1596 m_forward_listener_sp->AddEvent(event_sp); 1597 } 1598 } 1599 } 1600 } 1601 1602 lldb::thread_result_t Debugger::EventHandlerThread(lldb::thread_arg_t arg) { 1603 ((Debugger *)arg)->DefaultEventHandler(); 1604 return NULL; 1605 } 1606 1607 bool Debugger::StartEventHandlerThread() { 1608 if (!m_event_handler_thread.IsJoinable()) { 1609 // We must synchronize with the DefaultEventHandler() thread to ensure 1610 // it is up and running and listening to events before we return from 1611 // this function. We do this by listening to events for the 1612 // eBroadcastBitEventThreadIsListening from the m_sync_broadcaster 1613 ListenerSP listener_sp( 1614 Listener::MakeListener("lldb.debugger.event-handler")); 1615 listener_sp->StartListeningForEvents(&m_sync_broadcaster, 1616 eBroadcastBitEventThreadIsListening); 1617 1618 // Use larger 8MB stack for this thread 1619 m_event_handler_thread = ThreadLauncher::LaunchThread( 1620 "lldb.debugger.event-handler", EventHandlerThread, this, nullptr, 1621 g_debugger_event_thread_stack_bytes); 1622 1623 // Make sure DefaultEventHandler() is running and listening to events before 1624 // we return 1625 // from this function. We are only listening for events of type 1626 // eBroadcastBitEventThreadIsListening so we don't need to check the event, 1627 // we just need 1628 // to wait an infinite amount of time for it (nullptr timeout as the first 1629 // parameter) 1630 lldb::EventSP event_sp; 1631 listener_sp->GetEvent(event_sp, llvm::None); 1632 } 1633 return m_event_handler_thread.IsJoinable(); 1634 } 1635 1636 void Debugger::StopEventHandlerThread() { 1637 if (m_event_handler_thread.IsJoinable()) { 1638 GetCommandInterpreter().BroadcastEvent( 1639 CommandInterpreter::eBroadcastBitQuitCommandReceived); 1640 m_event_handler_thread.Join(nullptr); 1641 } 1642 } 1643 1644 lldb::thread_result_t Debugger::IOHandlerThread(lldb::thread_arg_t arg) { 1645 Debugger *debugger = (Debugger *)arg; 1646 debugger->ExecuteIOHandlers(); 1647 debugger->StopEventHandlerThread(); 1648 return NULL; 1649 } 1650 1651 bool Debugger::HasIOHandlerThread() { return m_io_handler_thread.IsJoinable(); } 1652 1653 bool Debugger::StartIOHandlerThread() { 1654 if (!m_io_handler_thread.IsJoinable()) 1655 m_io_handler_thread = ThreadLauncher::LaunchThread( 1656 "lldb.debugger.io-handler", IOHandlerThread, this, nullptr, 1657 8 * 1024 * 1024); // Use larger 8MB stack for this thread 1658 return m_io_handler_thread.IsJoinable(); 1659 } 1660 1661 void Debugger::StopIOHandlerThread() { 1662 if (m_io_handler_thread.IsJoinable()) { 1663 if (m_input_file_sp) 1664 m_input_file_sp->GetFile().Close(); 1665 m_io_handler_thread.Join(nullptr); 1666 } 1667 } 1668 1669 void Debugger::JoinIOHandlerThread() { 1670 if (HasIOHandlerThread()) { 1671 thread_result_t result; 1672 m_io_handler_thread.Join(&result); 1673 m_io_handler_thread = LLDB_INVALID_HOST_THREAD; 1674 } 1675 } 1676 1677 Target *Debugger::GetDummyTarget() { 1678 return m_target_list.GetDummyTarget(*this).get(); 1679 } 1680 1681 Target *Debugger::GetSelectedOrDummyTarget(bool prefer_dummy) { 1682 Target *target = nullptr; 1683 if (!prefer_dummy) { 1684 target = m_target_list.GetSelectedTarget().get(); 1685 if (target) 1686 return target; 1687 } 1688 1689 return GetDummyTarget(); 1690 } 1691 1692 Error Debugger::RunREPL(LanguageType language, const char *repl_options) { 1693 Error err; 1694 FileSpec repl_executable; 1695 1696 if (language == eLanguageTypeUnknown) { 1697 std::set<LanguageType> repl_languages; 1698 1699 Language::GetLanguagesSupportingREPLs(repl_languages); 1700 1701 if (repl_languages.size() == 1) { 1702 language = *repl_languages.begin(); 1703 } else if (repl_languages.empty()) { 1704 err.SetErrorStringWithFormat( 1705 "LLDB isn't configured with REPL support for any languages."); 1706 return err; 1707 } else { 1708 err.SetErrorStringWithFormat( 1709 "Multiple possible REPL languages. Please specify a language."); 1710 return err; 1711 } 1712 } 1713 1714 Target *const target = 1715 nullptr; // passing in an empty target means the REPL must create one 1716 1717 REPLSP repl_sp(REPL::Create(err, language, this, target, repl_options)); 1718 1719 if (!err.Success()) { 1720 return err; 1721 } 1722 1723 if (!repl_sp) { 1724 err.SetErrorStringWithFormat("couldn't find a REPL for %s", 1725 Language::GetNameForLanguageType(language)); 1726 return err; 1727 } 1728 1729 repl_sp->SetCompilerOptions(repl_options); 1730 repl_sp->RunLoop(); 1731 1732 return err; 1733 } 1734