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