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