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