1 //===-- Debugger.cpp --------------------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "lldb/Core/Debugger.h" 10 11 #include "lldb/Breakpoint/Breakpoint.h" 12 #include "lldb/Core/FormatEntity.h" 13 #include "lldb/Core/Mangled.h" 14 #include "lldb/Core/ModuleList.h" 15 #include "lldb/Core/PluginManager.h" 16 #include "lldb/Core/StreamAsynchronousIO.h" 17 #include "lldb/Core/StreamFile.h" 18 #include "lldb/DataFormatters/DataVisualization.h" 19 #include "lldb/Expression/REPL.h" 20 #include "lldb/Host/File.h" 21 #include "lldb/Host/FileSystem.h" 22 #include "lldb/Host/HostInfo.h" 23 #include "lldb/Host/Terminal.h" 24 #include "lldb/Host/ThreadLauncher.h" 25 #include "lldb/Interpreter/CommandInterpreter.h" 26 #include "lldb/Interpreter/OptionValue.h" 27 #include "lldb/Interpreter/OptionValueProperties.h" 28 #include "lldb/Interpreter/OptionValueSInt64.h" 29 #include "lldb/Interpreter/OptionValueString.h" 30 #include "lldb/Interpreter/Property.h" 31 #include "lldb/Interpreter/ScriptInterpreter.h" 32 #include "lldb/Symbol/Function.h" 33 #include "lldb/Symbol/Symbol.h" 34 #include "lldb/Symbol/SymbolContext.h" 35 #include "lldb/Target/Language.h" 36 #include "lldb/Target/Process.h" 37 #include "lldb/Target/StructuredDataPlugin.h" 38 #include "lldb/Target/Target.h" 39 #include "lldb/Target/TargetList.h" 40 #include "lldb/Target/Thread.h" 41 #include "lldb/Target/ThreadList.h" 42 #include "lldb/Utility/AnsiTerminal.h" 43 #include "lldb/Utility/Event.h" 44 #include "lldb/Utility/Listener.h" 45 #include "lldb/Utility/Log.h" 46 #include "lldb/Utility/Reproducer.h" 47 #include "lldb/Utility/State.h" 48 #include "lldb/Utility/Stream.h" 49 #include "lldb/Utility/StreamCallback.h" 50 #include "lldb/Utility/StreamString.h" 51 52 #if defined(_WIN32) 53 #include "lldb/Host/windows/PosixApi.h" 54 #include "lldb/Host/windows/windows.h" 55 #endif 56 57 #include "llvm/ADT/None.h" 58 #include "llvm/ADT/STLExtras.h" 59 #include "llvm/ADT/StringRef.h" 60 #include "llvm/ADT/iterator.h" 61 #include "llvm/Support/DynamicLibrary.h" 62 #include "llvm/Support/FileSystem.h" 63 #include "llvm/Support/Process.h" 64 #include "llvm/Support/Threading.h" 65 #include "llvm/Support/raw_ostream.h" 66 67 #include <list> 68 #include <memory> 69 #include <mutex> 70 #include <set> 71 #include <stdio.h> 72 #include <stdlib.h> 73 #include <string.h> 74 #include <string> 75 #include <system_error> 76 77 namespace lldb_private { 78 class Address; 79 } 80 81 using namespace lldb; 82 using namespace lldb_private; 83 84 static lldb::user_id_t g_unique_id = 1; 85 static size_t g_debugger_event_thread_stack_bytes = 8 * 1024 * 1024; 86 87 #pragma mark Static Functions 88 89 typedef std::vector<DebuggerSP> DebuggerList; 90 static std::recursive_mutex *g_debugger_list_mutex_ptr = 91 nullptr; // NOTE: intentional leak to avoid issues with C++ destructor chain 92 static DebuggerList *g_debugger_list_ptr = 93 nullptr; // NOTE: intentional leak to avoid issues with C++ destructor chain 94 95 static constexpr OptionEnumValueElement g_show_disassembly_enum_values[] = { 96 {Debugger::eStopDisassemblyTypeNever, "never", 97 "Never show disassembly when displaying a stop context."}, 98 {Debugger::eStopDisassemblyTypeNoDebugInfo, "no-debuginfo", 99 "Show disassembly when there is no debug information."}, 100 {Debugger::eStopDisassemblyTypeNoSource, "no-source", 101 "Show disassembly when there is no source information, or the source file " 102 "is missing when displaying a stop context."}, 103 {Debugger::eStopDisassemblyTypeAlways, "always", 104 "Always show disassembly when displaying a stop context."} }; 105 106 static constexpr OptionEnumValueElement g_language_enumerators[] = { 107 {eScriptLanguageNone, "none", "Disable scripting languages."}, 108 {eScriptLanguagePython, "python", 109 "Select python as the default scripting language."}, 110 {eScriptLanguageDefault, "default", 111 "Select the lldb default as the default scripting language."} }; 112 113 #define MODULE_WITH_FUNC \ 114 "{ " \ 115 "${module.file.basename}{`${function.name-with-args}" \ 116 "{${frame.no-debug}${function.pc-offset}}}}" 117 118 #define MODULE_WITH_FUNC_NO_ARGS \ 119 "{ " \ 120 "${module.file.basename}{`${function.name-without-args}" \ 121 "{${frame.no-debug}${function.pc-offset}}}}" 122 123 #define FILE_AND_LINE \ 124 "{ at ${line.file.basename}:${line.number}{:${line.column}}}" 125 #define IS_OPTIMIZED "{${function.is-optimized} [opt]}" 126 127 #define IS_ARTIFICIAL "{${frame.is-artificial} [artificial]}" 128 129 #define DEFAULT_THREAD_FORMAT \ 130 "thread #${thread.index}: tid = ${thread.id%tid}" \ 131 "{, ${frame.pc}}" MODULE_WITH_FUNC FILE_AND_LINE \ 132 "{, name = '${thread.name}'}" \ 133 "{, queue = '${thread.queue}'}" \ 134 "{, activity = '${thread.info.activity.name}'}" \ 135 "{, ${thread.info.trace_messages} messages}" \ 136 "{, stop reason = ${thread.stop-reason}}" \ 137 "{\\nReturn value: ${thread.return-value}}" \ 138 "{\\nCompleted expression: ${thread.completed-expression}}" \ 139 "\\n" 140 141 #define DEFAULT_THREAD_STOP_FORMAT \ 142 "thread #${thread.index}{, name = '${thread.name}'}" \ 143 "{, queue = '${thread.queue}'}" \ 144 "{, activity = '${thread.info.activity.name}'}" \ 145 "{, ${thread.info.trace_messages} messages}" \ 146 "{, stop reason = ${thread.stop-reason}}" \ 147 "{\\nReturn value: ${thread.return-value}}" \ 148 "{\\nCompleted expression: ${thread.completed-expression}}" \ 149 "\\n" 150 151 #define DEFAULT_FRAME_FORMAT \ 152 "frame #${frame.index}: ${frame.pc}" MODULE_WITH_FUNC FILE_AND_LINE \ 153 IS_OPTIMIZED IS_ARTIFICIAL "\\n" 154 155 #define DEFAULT_FRAME_FORMAT_NO_ARGS \ 156 "frame #${frame.index}: ${frame.pc}" MODULE_WITH_FUNC_NO_ARGS FILE_AND_LINE \ 157 IS_OPTIMIZED IS_ARTIFICIAL "\\n" 158 159 // Three parts to this disassembly format specification: 160 // 1. If this is a new function/symbol (no previous symbol/function), print 161 // dylib`funcname:\n 162 // 2. If this is a symbol context change (different from previous 163 // symbol/function), print 164 // dylib`funcname:\n 165 // 3. print 166 // address <+offset>: 167 #define DEFAULT_DISASSEMBLY_FORMAT \ 168 "{${function.initial-function}{${module.file.basename}`}{${function.name-" \ 169 "without-args}}:\\n}{${function.changed}\\n{${module.file.basename}`}{${" \ 170 "function.name-without-args}}:\\n}{${current-pc-arrow} " \ 171 "}${addr-file-or-load}{ " \ 172 "<${function.concrete-only-addr-offset-no-padding}>}: " 173 174 // gdb's disassembly format can be emulated with ${current-pc-arrow}${addr- 175 // file-or-load}{ <${function.name-without-args}${function.concrete-only-addr- 176 // offset-no-padding}>}: 177 178 // lldb's original format for disassembly would look like this format string - 179 // {${function.initial-function}{${module.file.basename}`}{${function.name- 180 // without- 181 // args}}:\n}{${function.changed}\n{${module.file.basename}`}{${function.name- 182 // without-args}}:\n}{${current-pc-arrow} }{${addr-file-or-load}}: 183 184 static constexpr OptionEnumValueElement s_stop_show_column_values[] = { 185 {eStopShowColumnAnsiOrCaret, "ansi-or-caret", 186 "Highlight the stop column with ANSI terminal codes when color/ANSI mode " 187 "is enabled; otherwise, fall back to using a text-only caret (^) as if " 188 "\"caret-only\" mode was selected."}, 189 {eStopShowColumnAnsi, "ansi", "Highlight the stop column with ANSI " 190 "terminal codes when running LLDB with " 191 "color/ANSI enabled."}, 192 {eStopShowColumnCaret, "caret", 193 "Highlight the stop column with a caret character (^) underneath the stop " 194 "column. This method introduces a new line in source listings that " 195 "display thread stop locations."}, 196 {eStopShowColumnNone, "none", "Do not highlight the stop column."}}; 197 198 static constexpr PropertyDefinition g_properties[] = { 199 {"auto-confirm", OptionValue::eTypeBoolean, true, false, nullptr, {}, 200 "If true all confirmation prompts will receive their default reply."}, 201 {"disassembly-format", OptionValue::eTypeFormatEntity, true, 0, 202 DEFAULT_DISASSEMBLY_FORMAT, {}, 203 "The default disassembly format " 204 "string to use when disassembling " 205 "instruction sequences."}, 206 {"frame-format", OptionValue::eTypeFormatEntity, true, 0, 207 DEFAULT_FRAME_FORMAT, {}, 208 "The default frame format string to use " 209 "when displaying stack frame information " 210 "for threads."}, 211 {"notify-void", OptionValue::eTypeBoolean, true, false, nullptr, {}, 212 "Notify the user explicitly if an expression returns void (default: " 213 "false)."}, 214 {"prompt", OptionValue::eTypeString, true, 215 OptionValueString::eOptionEncodeCharacterEscapeSequences, "(lldb) ", {}, 216 "The debugger command line prompt displayed for the user."}, 217 {"script-lang", OptionValue::eTypeEnum, true, eScriptLanguagePython, 218 nullptr, OptionEnumValues(g_language_enumerators), 219 "The script language to be used for evaluating user-written scripts."}, 220 {"stop-disassembly-count", OptionValue::eTypeSInt64, true, 4, nullptr, {}, 221 "The number of disassembly lines to show when displaying a " 222 "stopped context."}, 223 {"stop-disassembly-display", OptionValue::eTypeEnum, true, 224 Debugger::eStopDisassemblyTypeNoDebugInfo, nullptr, 225 OptionEnumValues(g_show_disassembly_enum_values), 226 "Control when to display disassembly when displaying a stopped context."}, 227 {"stop-line-count-after", OptionValue::eTypeSInt64, true, 3, nullptr, {}, 228 "The number of sources lines to display that come after the " 229 "current source line when displaying a stopped context."}, 230 {"stop-line-count-before", OptionValue::eTypeSInt64, true, 3, nullptr, {}, 231 "The number of sources lines to display that come before the " 232 "current source line when displaying a stopped context."}, 233 {"highlight-source", OptionValue::eTypeBoolean, true, true, nullptr, {}, 234 "If true, LLDB will highlight the displayed source code."}, 235 {"stop-show-column", OptionValue::eTypeEnum, false, 236 eStopShowColumnAnsiOrCaret, nullptr, OptionEnumValues(s_stop_show_column_values), 237 "If true, LLDB will use the column information from the debug info to " 238 "mark the current position when displaying a stopped context."}, 239 {"stop-show-column-ansi-prefix", OptionValue::eTypeString, true, 0, 240 "${ansi.underline}", {}, 241 "When displaying the column marker in a color-enabled (i.e. ANSI) " 242 "terminal, use the ANSI terminal code specified in this format at the " 243 "immediately before the column to be marked."}, 244 {"stop-show-column-ansi-suffix", OptionValue::eTypeString, true, 0, 245 "${ansi.normal}", {}, 246 "When displaying the column marker in a color-enabled (i.e. ANSI) " 247 "terminal, use the ANSI terminal code specified in this format " 248 "immediately after the column to be marked."}, 249 {"term-width", OptionValue::eTypeSInt64, true, 80, nullptr, {}, 250 "The maximum number of columns to use for displaying text."}, 251 {"thread-format", OptionValue::eTypeFormatEntity, true, 0, 252 DEFAULT_THREAD_FORMAT, {}, 253 "The default thread format string to use " 254 "when displaying thread information."}, 255 {"thread-stop-format", OptionValue::eTypeFormatEntity, true, 0, 256 DEFAULT_THREAD_STOP_FORMAT, {}, 257 "The default thread format " 258 "string to use when displaying thread " 259 "information as part of the stop display."}, 260 {"use-external-editor", OptionValue::eTypeBoolean, true, false, nullptr, {}, 261 "Whether to use an external editor or not."}, 262 {"use-color", OptionValue::eTypeBoolean, true, true, nullptr, {}, 263 "Whether to use Ansi color codes or not."}, 264 {"auto-one-line-summaries", OptionValue::eTypeBoolean, true, true, nullptr, 265 {}, 266 "If true, LLDB will automatically display small structs in " 267 "one-liner format (default: true)."}, 268 {"auto-indent", OptionValue::eTypeBoolean, true, true, nullptr, {}, 269 "If true, LLDB will auto indent/outdent code. Currently only supported in " 270 "the REPL (default: true)."}, 271 {"print-decls", OptionValue::eTypeBoolean, true, true, nullptr, {}, 272 "If true, LLDB will print the values of variables declared in an " 273 "expression. Currently only supported in the REPL (default: true)."}, 274 {"tab-size", OptionValue::eTypeUInt64, true, 4, nullptr, {}, 275 "The tab size to use when indenting code in multi-line input mode " 276 "(default: 4)."}, 277 {"escape-non-printables", OptionValue::eTypeBoolean, true, true, nullptr, 278 {}, 279 "If true, LLDB will automatically escape non-printable and " 280 "escape characters when formatting strings."}, 281 {"frame-format-unique", OptionValue::eTypeFormatEntity, true, 0, 282 DEFAULT_FRAME_FORMAT_NO_ARGS, {}, 283 "The default frame format string to use when displaying stack frame" 284 "information for threads from thread backtrace unique."}}; 285 286 enum { 287 ePropertyAutoConfirm = 0, 288 ePropertyDisassemblyFormat, 289 ePropertyFrameFormat, 290 ePropertyNotiftVoid, 291 ePropertyPrompt, 292 ePropertyScriptLanguage, 293 ePropertyStopDisassemblyCount, 294 ePropertyStopDisassemblyDisplay, 295 ePropertyStopLineCountAfter, 296 ePropertyStopLineCountBefore, 297 ePropertyHighlightSource, 298 ePropertyStopShowColumn, 299 ePropertyStopShowColumnAnsiPrefix, 300 ePropertyStopShowColumnAnsiSuffix, 301 ePropertyTerminalWidth, 302 ePropertyThreadFormat, 303 ePropertyThreadStopFormat, 304 ePropertyUseExternalEditor, 305 ePropertyUseColor, 306 ePropertyAutoOneLineSummaries, 307 ePropertyAutoIndent, 308 ePropertyPrintDecls, 309 ePropertyTabSize, 310 ePropertyEscapeNonPrintables, 311 ePropertyFrameFormatUnique, 312 }; 313 314 LoadPluginCallbackType Debugger::g_load_plugin_callback = nullptr; 315 316 Status Debugger::SetPropertyValue(const ExecutionContext *exe_ctx, 317 VarSetOperationType op, 318 llvm::StringRef property_path, 319 llvm::StringRef value) { 320 bool is_load_script = (property_path == "target.load-script-from-symbol-file"); 321 bool is_escape_non_printables = (property_path == "escape-non-printables"); 322 TargetSP target_sp; 323 LoadScriptFromSymFile load_script_old_value; 324 if (is_load_script && exe_ctx->GetTargetSP()) { 325 target_sp = exe_ctx->GetTargetSP(); 326 load_script_old_value = 327 target_sp->TargetProperties::GetLoadScriptFromSymbolFile(); 328 } 329 Status error(Properties::SetPropertyValue(exe_ctx, op, property_path, value)); 330 if (error.Success()) { 331 // FIXME it would be nice to have "on-change" callbacks for properties 332 if (property_path == g_properties[ePropertyPrompt].name) { 333 llvm::StringRef new_prompt = GetPrompt(); 334 std::string str = lldb_utility::ansi::FormatAnsiTerminalCodes( 335 new_prompt, GetUseColor()); 336 if (str.length()) 337 new_prompt = str; 338 GetCommandInterpreter().UpdatePrompt(new_prompt); 339 auto bytes = llvm::make_unique<EventDataBytes>(new_prompt); 340 auto prompt_change_event_sp = std::make_shared<Event>( 341 CommandInterpreter::eBroadcastBitResetPrompt, bytes.release()); 342 GetCommandInterpreter().BroadcastEvent(prompt_change_event_sp); 343 } else if (property_path == g_properties[ePropertyUseColor].name) { 344 // use-color changed. Ping the prompt so it can reset the ansi terminal 345 // codes. 346 SetPrompt(GetPrompt()); 347 } else if (is_load_script && target_sp && 348 load_script_old_value == eLoadScriptFromSymFileWarn) { 349 if (target_sp->TargetProperties::GetLoadScriptFromSymbolFile() == 350 eLoadScriptFromSymFileTrue) { 351 std::list<Status> errors; 352 StreamString feedback_stream; 353 if (!target_sp->LoadScriptingResources(errors, &feedback_stream)) { 354 StreamFileSP stream_sp(GetErrorFile()); 355 if (stream_sp) { 356 for (auto error : errors) { 357 stream_sp->Printf("%s\n", error.AsCString()); 358 } 359 if (feedback_stream.GetSize()) 360 stream_sp->PutCString(feedback_stream.GetString()); 361 } 362 } 363 } 364 } else if (is_escape_non_printables) { 365 DataVisualization::ForceUpdate(); 366 } 367 } 368 return error; 369 } 370 371 bool Debugger::GetAutoConfirm() const { 372 const uint32_t idx = ePropertyAutoConfirm; 373 return m_collection_sp->GetPropertyAtIndexAsBoolean( 374 nullptr, idx, g_properties[idx].default_uint_value != 0); 375 } 376 377 const FormatEntity::Entry *Debugger::GetDisassemblyFormat() const { 378 const uint32_t idx = ePropertyDisassemblyFormat; 379 return m_collection_sp->GetPropertyAtIndexAsFormatEntity(nullptr, idx); 380 } 381 382 const FormatEntity::Entry *Debugger::GetFrameFormat() const { 383 const uint32_t idx = ePropertyFrameFormat; 384 return m_collection_sp->GetPropertyAtIndexAsFormatEntity(nullptr, idx); 385 } 386 387 const FormatEntity::Entry *Debugger::GetFrameFormatUnique() const { 388 const uint32_t idx = ePropertyFrameFormatUnique; 389 return m_collection_sp->GetPropertyAtIndexAsFormatEntity(nullptr, idx); 390 } 391 392 bool Debugger::GetNotifyVoid() const { 393 const uint32_t idx = ePropertyNotiftVoid; 394 return m_collection_sp->GetPropertyAtIndexAsBoolean( 395 nullptr, idx, g_properties[idx].default_uint_value != 0); 396 } 397 398 llvm::StringRef Debugger::GetPrompt() const { 399 const uint32_t idx = ePropertyPrompt; 400 return m_collection_sp->GetPropertyAtIndexAsString( 401 nullptr, idx, g_properties[idx].default_cstr_value); 402 } 403 404 void Debugger::SetPrompt(llvm::StringRef p) { 405 const uint32_t idx = ePropertyPrompt; 406 m_collection_sp->SetPropertyAtIndexAsString(nullptr, idx, p); 407 llvm::StringRef new_prompt = GetPrompt(); 408 std::string str = 409 lldb_utility::ansi::FormatAnsiTerminalCodes(new_prompt, GetUseColor()); 410 if (str.length()) 411 new_prompt = str; 412 GetCommandInterpreter().UpdatePrompt(new_prompt); 413 } 414 415 llvm::StringRef Debugger::GetReproducerPath() const { 416 auto &r = repro::Reproducer::Instance(); 417 return r.GetReproducerPath().GetCString(); 418 } 419 420 const FormatEntity::Entry *Debugger::GetThreadFormat() const { 421 const uint32_t idx = ePropertyThreadFormat; 422 return m_collection_sp->GetPropertyAtIndexAsFormatEntity(nullptr, idx); 423 } 424 425 const FormatEntity::Entry *Debugger::GetThreadStopFormat() const { 426 const uint32_t idx = ePropertyThreadStopFormat; 427 return m_collection_sp->GetPropertyAtIndexAsFormatEntity(nullptr, idx); 428 } 429 430 lldb::ScriptLanguage Debugger::GetScriptLanguage() const { 431 const uint32_t idx = ePropertyScriptLanguage; 432 return (lldb::ScriptLanguage)m_collection_sp->GetPropertyAtIndexAsEnumeration( 433 nullptr, idx, g_properties[idx].default_uint_value); 434 } 435 436 bool Debugger::SetScriptLanguage(lldb::ScriptLanguage script_lang) { 437 const uint32_t idx = ePropertyScriptLanguage; 438 return m_collection_sp->SetPropertyAtIndexAsEnumeration(nullptr, idx, 439 script_lang); 440 } 441 442 uint32_t Debugger::GetTerminalWidth() const { 443 const uint32_t idx = ePropertyTerminalWidth; 444 return m_collection_sp->GetPropertyAtIndexAsSInt64( 445 nullptr, idx, g_properties[idx].default_uint_value); 446 } 447 448 bool Debugger::SetTerminalWidth(uint32_t term_width) { 449 const uint32_t idx = ePropertyTerminalWidth; 450 return m_collection_sp->SetPropertyAtIndexAsSInt64(nullptr, idx, term_width); 451 } 452 453 bool Debugger::GetUseExternalEditor() const { 454 const uint32_t idx = ePropertyUseExternalEditor; 455 return m_collection_sp->GetPropertyAtIndexAsBoolean( 456 nullptr, idx, g_properties[idx].default_uint_value != 0); 457 } 458 459 bool Debugger::SetUseExternalEditor(bool b) { 460 const uint32_t idx = ePropertyUseExternalEditor; 461 return m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b); 462 } 463 464 bool Debugger::GetUseColor() const { 465 const uint32_t idx = ePropertyUseColor; 466 return m_collection_sp->GetPropertyAtIndexAsBoolean( 467 nullptr, idx, g_properties[idx].default_uint_value != 0); 468 } 469 470 bool Debugger::SetUseColor(bool b) { 471 const uint32_t idx = ePropertyUseColor; 472 bool ret = m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b); 473 SetPrompt(GetPrompt()); 474 return ret; 475 } 476 477 bool Debugger::GetHighlightSource() const { 478 const uint32_t idx = ePropertyHighlightSource; 479 return m_collection_sp->GetPropertyAtIndexAsBoolean( 480 nullptr, idx, g_properties[idx].default_uint_value); 481 } 482 483 StopShowColumn Debugger::GetStopShowColumn() const { 484 const uint32_t idx = ePropertyStopShowColumn; 485 return (lldb::StopShowColumn)m_collection_sp->GetPropertyAtIndexAsEnumeration( 486 nullptr, idx, g_properties[idx].default_uint_value); 487 } 488 489 llvm::StringRef Debugger::GetStopShowColumnAnsiPrefix() const { 490 const uint32_t idx = ePropertyStopShowColumnAnsiPrefix; 491 return m_collection_sp->GetPropertyAtIndexAsString(nullptr, idx, ""); 492 } 493 494 llvm::StringRef Debugger::GetStopShowColumnAnsiSuffix() const { 495 const uint32_t idx = ePropertyStopShowColumnAnsiSuffix; 496 return m_collection_sp->GetPropertyAtIndexAsString(nullptr, idx, ""); 497 } 498 499 uint32_t Debugger::GetStopSourceLineCount(bool before) const { 500 const uint32_t idx = 501 before ? ePropertyStopLineCountBefore : ePropertyStopLineCountAfter; 502 return m_collection_sp->GetPropertyAtIndexAsSInt64( 503 nullptr, idx, g_properties[idx].default_uint_value); 504 } 505 506 Debugger::StopDisassemblyType Debugger::GetStopDisassemblyDisplay() const { 507 const uint32_t idx = ePropertyStopDisassemblyDisplay; 508 return (Debugger::StopDisassemblyType) 509 m_collection_sp->GetPropertyAtIndexAsEnumeration( 510 nullptr, idx, g_properties[idx].default_uint_value); 511 } 512 513 uint32_t Debugger::GetDisassemblyLineCount() const { 514 const uint32_t idx = ePropertyStopDisassemblyCount; 515 return m_collection_sp->GetPropertyAtIndexAsSInt64( 516 nullptr, idx, g_properties[idx].default_uint_value); 517 } 518 519 bool Debugger::GetAutoOneLineSummaries() const { 520 const uint32_t idx = ePropertyAutoOneLineSummaries; 521 return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, true); 522 } 523 524 bool Debugger::GetEscapeNonPrintables() const { 525 const uint32_t idx = ePropertyEscapeNonPrintables; 526 return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, true); 527 } 528 529 bool Debugger::GetAutoIndent() const { 530 const uint32_t idx = ePropertyAutoIndent; 531 return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, true); 532 } 533 534 bool Debugger::SetAutoIndent(bool b) { 535 const uint32_t idx = ePropertyAutoIndent; 536 return m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b); 537 } 538 539 bool Debugger::GetPrintDecls() const { 540 const uint32_t idx = ePropertyPrintDecls; 541 return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, true); 542 } 543 544 bool Debugger::SetPrintDecls(bool b) { 545 const uint32_t idx = ePropertyPrintDecls; 546 return m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b); 547 } 548 549 uint32_t Debugger::GetTabSize() const { 550 const uint32_t idx = ePropertyTabSize; 551 return m_collection_sp->GetPropertyAtIndexAsUInt64( 552 nullptr, idx, g_properties[idx].default_uint_value); 553 } 554 555 bool Debugger::SetTabSize(uint32_t tab_size) { 556 const uint32_t idx = ePropertyTabSize; 557 return m_collection_sp->SetPropertyAtIndexAsUInt64(nullptr, idx, tab_size); 558 } 559 560 #pragma mark Debugger 561 562 // const DebuggerPropertiesSP & 563 // Debugger::GetSettings() const 564 //{ 565 // return m_properties_sp; 566 //} 567 // 568 569 void Debugger::Initialize(LoadPluginCallbackType load_plugin_callback) { 570 assert(g_debugger_list_ptr == nullptr && 571 "Debugger::Initialize called more than once!"); 572 g_debugger_list_mutex_ptr = new std::recursive_mutex(); 573 g_debugger_list_ptr = new DebuggerList(); 574 g_load_plugin_callback = load_plugin_callback; 575 } 576 577 void Debugger::Terminate() { 578 assert(g_debugger_list_ptr && 579 "Debugger::Terminate called without a matching Debugger::Initialize!"); 580 581 if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) { 582 // Clear our master list of debugger objects 583 { 584 std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr); 585 for (const auto &debugger : *g_debugger_list_ptr) 586 debugger->Clear(); 587 g_debugger_list_ptr->clear(); 588 } 589 } 590 } 591 592 void Debugger::SettingsInitialize() { Target::SettingsInitialize(); } 593 594 void Debugger::SettingsTerminate() { Target::SettingsTerminate(); } 595 596 bool Debugger::LoadPlugin(const FileSpec &spec, Status &error) { 597 if (g_load_plugin_callback) { 598 llvm::sys::DynamicLibrary dynlib = 599 g_load_plugin_callback(shared_from_this(), spec, error); 600 if (dynlib.isValid()) { 601 m_loaded_plugins.push_back(dynlib); 602 return true; 603 } 604 } else { 605 // The g_load_plugin_callback is registered in SBDebugger::Initialize() and 606 // if the public API layer isn't available (code is linking against all of 607 // the internal LLDB static libraries), then we can't load plugins 608 error.SetErrorString("Public API layer is not available"); 609 } 610 return false; 611 } 612 613 static FileSystem::EnumerateDirectoryResult 614 LoadPluginCallback(void *baton, llvm::sys::fs::file_type ft, 615 llvm::StringRef path) { 616 Status error; 617 618 static ConstString g_dylibext(".dylib"); 619 static ConstString g_solibext(".so"); 620 621 if (!baton) 622 return FileSystem::eEnumerateDirectoryResultQuit; 623 624 Debugger *debugger = (Debugger *)baton; 625 626 namespace fs = llvm::sys::fs; 627 // If we have a regular file, a symbolic link or unknown file type, try and 628 // process the file. We must handle unknown as sometimes the directory 629 // enumeration might be enumerating a file system that doesn't have correct 630 // file type information. 631 if (ft == fs::file_type::regular_file || ft == fs::file_type::symlink_file || 632 ft == fs::file_type::type_unknown) { 633 FileSpec plugin_file_spec(path); 634 FileSystem::Instance().Resolve(plugin_file_spec); 635 636 if (plugin_file_spec.GetFileNameExtension() != g_dylibext && 637 plugin_file_spec.GetFileNameExtension() != g_solibext) { 638 return FileSystem::eEnumerateDirectoryResultNext; 639 } 640 641 Status plugin_load_error; 642 debugger->LoadPlugin(plugin_file_spec, plugin_load_error); 643 644 return FileSystem::eEnumerateDirectoryResultNext; 645 } else if (ft == fs::file_type::directory_file || 646 ft == fs::file_type::symlink_file || 647 ft == fs::file_type::type_unknown) { 648 // Try and recurse into anything that a directory or symbolic link. We must 649 // also do this for unknown as sometimes the directory enumeration might be 650 // enumerating a file system that doesn't have correct file type 651 // information. 652 return FileSystem::eEnumerateDirectoryResultEnter; 653 } 654 655 return FileSystem::eEnumerateDirectoryResultNext; 656 } 657 658 void Debugger::InstanceInitialize() { 659 const bool find_directories = true; 660 const bool find_files = true; 661 const bool find_other = true; 662 char dir_path[PATH_MAX]; 663 if (FileSpec dir_spec = HostInfo::GetSystemPluginDir()) { 664 if (FileSystem::Instance().Exists(dir_spec) && 665 dir_spec.GetPath(dir_path, sizeof(dir_path))) { 666 FileSystem::Instance().EnumerateDirectory(dir_path, find_directories, 667 find_files, find_other, 668 LoadPluginCallback, this); 669 } 670 } 671 672 if (FileSpec dir_spec = HostInfo::GetUserPluginDir()) { 673 if (FileSystem::Instance().Exists(dir_spec) && 674 dir_spec.GetPath(dir_path, sizeof(dir_path))) { 675 FileSystem::Instance().EnumerateDirectory(dir_path, find_directories, 676 find_files, find_other, 677 LoadPluginCallback, this); 678 } 679 } 680 681 PluginManager::DebuggerInitialize(*this); 682 } 683 684 DebuggerSP Debugger::CreateInstance(lldb::LogOutputCallback log_callback, 685 void *baton) { 686 DebuggerSP debugger_sp(new Debugger(log_callback, baton)); 687 if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) { 688 std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr); 689 g_debugger_list_ptr->push_back(debugger_sp); 690 } 691 debugger_sp->InstanceInitialize(); 692 return debugger_sp; 693 } 694 695 void Debugger::Destroy(DebuggerSP &debugger_sp) { 696 if (!debugger_sp) 697 return; 698 699 debugger_sp->Clear(); 700 701 if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) { 702 std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr); 703 DebuggerList::iterator pos, end = g_debugger_list_ptr->end(); 704 for (pos = g_debugger_list_ptr->begin(); pos != end; ++pos) { 705 if ((*pos).get() == debugger_sp.get()) { 706 g_debugger_list_ptr->erase(pos); 707 return; 708 } 709 } 710 } 711 } 712 713 DebuggerSP 714 Debugger::FindDebuggerWithInstanceName(ConstString instance_name) { 715 DebuggerSP debugger_sp; 716 if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) { 717 std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr); 718 DebuggerList::iterator pos, end = g_debugger_list_ptr->end(); 719 for (pos = g_debugger_list_ptr->begin(); pos != end; ++pos) { 720 if ((*pos)->m_instance_name == instance_name) { 721 debugger_sp = *pos; 722 break; 723 } 724 } 725 } 726 return debugger_sp; 727 } 728 729 TargetSP Debugger::FindTargetWithProcessID(lldb::pid_t pid) { 730 TargetSP target_sp; 731 if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) { 732 std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr); 733 DebuggerList::iterator pos, end = g_debugger_list_ptr->end(); 734 for (pos = g_debugger_list_ptr->begin(); pos != end; ++pos) { 735 target_sp = (*pos)->GetTargetList().FindTargetWithProcessID(pid); 736 if (target_sp) 737 break; 738 } 739 } 740 return target_sp; 741 } 742 743 TargetSP Debugger::FindTargetWithProcess(Process *process) { 744 TargetSP target_sp; 745 if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) { 746 std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr); 747 DebuggerList::iterator pos, end = g_debugger_list_ptr->end(); 748 for (pos = g_debugger_list_ptr->begin(); pos != end; ++pos) { 749 target_sp = (*pos)->GetTargetList().FindTargetWithProcess(process); 750 if (target_sp) 751 break; 752 } 753 } 754 return target_sp; 755 } 756 757 Debugger::Debugger(lldb::LogOutputCallback log_callback, void *baton) 758 : UserID(g_unique_id++), 759 Properties(std::make_shared<OptionValueProperties>()), 760 m_input_file_sp(std::make_shared<StreamFile>(stdin, false)), 761 m_output_file_sp(std::make_shared<StreamFile>(stdout, false)), 762 m_error_file_sp(std::make_shared<StreamFile>(stderr, false)), 763 m_input_recorder(nullptr), 764 m_broadcaster_manager_sp(BroadcasterManager::MakeBroadcasterManager()), 765 m_terminal_state(), m_target_list(*this), m_platform_list(), 766 m_listener_sp(Listener::MakeListener("lldb.Debugger")), 767 m_source_manager_up(), m_source_file_cache(), 768 m_command_interpreter_up( 769 llvm::make_unique<CommandInterpreter>(*this, false)), 770 m_script_interpreter_sp(), m_input_reader_stack(), m_instance_name(), 771 m_loaded_plugins(), m_event_handler_thread(), m_io_handler_thread(), 772 m_sync_broadcaster(nullptr, "lldb.debugger.sync"), 773 m_forward_listener_sp(), m_clear_once() { 774 char instance_cstr[256]; 775 snprintf(instance_cstr, sizeof(instance_cstr), "debugger_%d", (int)GetID()); 776 m_instance_name.SetCString(instance_cstr); 777 if (log_callback) 778 m_log_callback_stream_sp = 779 std::make_shared<StreamCallback>(log_callback, baton); 780 m_command_interpreter_up->Initialize(); 781 // Always add our default platform to the platform list 782 PlatformSP default_platform_sp(Platform::GetHostPlatform()); 783 assert(default_platform_sp); 784 m_platform_list.Append(default_platform_sp, true); 785 786 m_collection_sp->Initialize(g_properties); 787 m_collection_sp->AppendProperty( 788 ConstString("target"), 789 ConstString("Settings specify to debugging targets."), true, 790 Target::GetGlobalProperties()->GetValueProperties()); 791 m_collection_sp->AppendProperty( 792 ConstString("platform"), ConstString("Platform settings."), true, 793 Platform::GetGlobalPlatformProperties()->GetValueProperties()); 794 m_collection_sp->AppendProperty( 795 ConstString("symbols"), ConstString("Symbol lookup and cache settings."), 796 true, ModuleList::GetGlobalModuleListProperties().GetValueProperties()); 797 if (m_command_interpreter_up) { 798 m_collection_sp->AppendProperty( 799 ConstString("interpreter"), 800 ConstString("Settings specify to the debugger's command interpreter."), 801 true, m_command_interpreter_up->GetValueProperties()); 802 } 803 OptionValueSInt64 *term_width = 804 m_collection_sp->GetPropertyAtIndexAsOptionValueSInt64( 805 nullptr, ePropertyTerminalWidth); 806 term_width->SetMinimumValue(10); 807 term_width->SetMaximumValue(1024); 808 809 // Turn off use-color if this is a dumb terminal. 810 const char *term = getenv("TERM"); 811 if (term && !strcmp(term, "dumb")) 812 SetUseColor(false); 813 // Turn off use-color if we don't write to a terminal with color support. 814 if (!m_output_file_sp->GetFile().GetIsTerminalWithColors()) 815 SetUseColor(false); 816 817 #if defined(_WIN32) && defined(ENABLE_VIRTUAL_TERMINAL_PROCESSING) 818 // Enabling use of ANSI color codes because LLDB is using them to highlight 819 // text. 820 llvm::sys::Process::UseANSIEscapeCodes(true); 821 #endif 822 } 823 824 Debugger::~Debugger() { Clear(); } 825 826 void Debugger::Clear() { 827 // Make sure we call this function only once. With the C++ global destructor 828 // chain having a list of debuggers and with code that can be running on 829 // other threads, we need to ensure this doesn't happen multiple times. 830 // 831 // The following functions call Debugger::Clear(): 832 // Debugger::~Debugger(); 833 // static void Debugger::Destroy(lldb::DebuggerSP &debugger_sp); 834 // static void Debugger::Terminate(); 835 llvm::call_once(m_clear_once, [this]() { 836 ClearIOHandlers(); 837 StopIOHandlerThread(); 838 StopEventHandlerThread(); 839 m_listener_sp->Clear(); 840 int num_targets = m_target_list.GetNumTargets(); 841 for (int i = 0; i < num_targets; i++) { 842 TargetSP target_sp(m_target_list.GetTargetAtIndex(i)); 843 if (target_sp) { 844 ProcessSP process_sp(target_sp->GetProcessSP()); 845 if (process_sp) 846 process_sp->Finalize(); 847 target_sp->Destroy(); 848 } 849 } 850 m_broadcaster_manager_sp->Clear(); 851 852 // Close the input file _before_ we close the input read communications 853 // class as it does NOT own the input file, our m_input_file does. 854 m_terminal_state.Clear(); 855 if (m_input_file_sp) 856 m_input_file_sp->GetFile().Close(); 857 858 m_command_interpreter_up->Clear(); 859 }); 860 } 861 862 bool Debugger::GetCloseInputOnEOF() const { 863 // return m_input_comm.GetCloseOnEOF(); 864 return false; 865 } 866 867 void Debugger::SetCloseInputOnEOF(bool b) { 868 // m_input_comm.SetCloseOnEOF(b); 869 } 870 871 bool Debugger::GetAsyncExecution() { 872 return !m_command_interpreter_up->GetSynchronous(); 873 } 874 875 void Debugger::SetAsyncExecution(bool async_execution) { 876 m_command_interpreter_up->SetSynchronous(!async_execution); 877 } 878 879 repro::DataRecorder *Debugger::GetInputRecorder() { return m_input_recorder; } 880 881 void Debugger::SetInputFileHandle(FILE *fh, bool tranfer_ownership, 882 repro::DataRecorder *recorder) { 883 m_input_recorder = recorder; 884 if (m_input_file_sp) 885 m_input_file_sp->GetFile().SetStream(fh, tranfer_ownership); 886 else 887 m_input_file_sp = std::make_shared<StreamFile>(fh, tranfer_ownership); 888 889 File &in_file = m_input_file_sp->GetFile(); 890 if (!in_file.IsValid()) 891 in_file.SetStream(stdin, true); 892 893 // Save away the terminal state if that is relevant, so that we can restore 894 // it in RestoreInputState. 895 SaveInputTerminalState(); 896 } 897 898 void Debugger::SetOutputFileHandle(FILE *fh, bool tranfer_ownership) { 899 if (m_output_file_sp) 900 m_output_file_sp->GetFile().SetStream(fh, tranfer_ownership); 901 else 902 m_output_file_sp = std::make_shared<StreamFile>(fh, tranfer_ownership); 903 904 File &out_file = m_output_file_sp->GetFile(); 905 if (!out_file.IsValid()) 906 out_file.SetStream(stdout, false); 907 908 // Do not create the ScriptInterpreter just for setting the output file 909 // handle as the constructor will know how to do the right thing on its own. 910 if (ScriptInterpreter *script_interpreter = 911 GetScriptInterpreter(/*can_create=*/false)) 912 script_interpreter->ResetOutputFileHandle(fh); 913 } 914 915 void Debugger::SetErrorFileHandle(FILE *fh, bool tranfer_ownership) { 916 if (m_error_file_sp) 917 m_error_file_sp->GetFile().SetStream(fh, tranfer_ownership); 918 else 919 m_error_file_sp = std::make_shared<StreamFile>(fh, tranfer_ownership); 920 921 File &err_file = m_error_file_sp->GetFile(); 922 if (!err_file.IsValid()) 923 err_file.SetStream(stderr, false); 924 } 925 926 void Debugger::SaveInputTerminalState() { 927 if (m_input_file_sp) { 928 File &in_file = m_input_file_sp->GetFile(); 929 if (in_file.GetDescriptor() != File::kInvalidDescriptor) 930 m_terminal_state.Save(in_file.GetDescriptor(), true); 931 } 932 } 933 934 void Debugger::RestoreInputTerminalState() { m_terminal_state.Restore(); } 935 936 ExecutionContext Debugger::GetSelectedExecutionContext() { 937 ExecutionContext exe_ctx; 938 TargetSP target_sp(GetSelectedTarget()); 939 exe_ctx.SetTargetSP(target_sp); 940 941 if (target_sp) { 942 ProcessSP process_sp(target_sp->GetProcessSP()); 943 exe_ctx.SetProcessSP(process_sp); 944 if (process_sp && !process_sp->IsRunning()) { 945 ThreadSP thread_sp(process_sp->GetThreadList().GetSelectedThread()); 946 if (thread_sp) { 947 exe_ctx.SetThreadSP(thread_sp); 948 exe_ctx.SetFrameSP(thread_sp->GetSelectedFrame()); 949 if (exe_ctx.GetFramePtr() == nullptr) 950 exe_ctx.SetFrameSP(thread_sp->GetStackFrameAtIndex(0)); 951 } 952 } 953 } 954 return exe_ctx; 955 } 956 957 void Debugger::DispatchInputInterrupt() { 958 std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex()); 959 IOHandlerSP reader_sp(m_input_reader_stack.Top()); 960 if (reader_sp) 961 reader_sp->Interrupt(); 962 } 963 964 void Debugger::DispatchInputEndOfFile() { 965 std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex()); 966 IOHandlerSP reader_sp(m_input_reader_stack.Top()); 967 if (reader_sp) 968 reader_sp->GotEOF(); 969 } 970 971 void Debugger::ClearIOHandlers() { 972 // The bottom input reader should be the main debugger input reader. We do 973 // not want to close that one here. 974 std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex()); 975 while (m_input_reader_stack.GetSize() > 1) { 976 IOHandlerSP reader_sp(m_input_reader_stack.Top()); 977 if (reader_sp) 978 PopIOHandler(reader_sp); 979 } 980 } 981 982 void Debugger::ExecuteIOHandlers() { 983 while (true) { 984 IOHandlerSP reader_sp(m_input_reader_stack.Top()); 985 if (!reader_sp) 986 break; 987 988 reader_sp->Run(); 989 990 // Remove all input readers that are done from the top of the stack 991 while (true) { 992 IOHandlerSP top_reader_sp = m_input_reader_stack.Top(); 993 if (top_reader_sp && top_reader_sp->GetIsDone()) 994 PopIOHandler(top_reader_sp); 995 else 996 break; 997 } 998 } 999 ClearIOHandlers(); 1000 } 1001 1002 bool Debugger::IsTopIOHandler(const lldb::IOHandlerSP &reader_sp) { 1003 return m_input_reader_stack.IsTop(reader_sp); 1004 } 1005 1006 bool Debugger::CheckTopIOHandlerTypes(IOHandler::Type top_type, 1007 IOHandler::Type second_top_type) { 1008 return m_input_reader_stack.CheckTopIOHandlerTypes(top_type, second_top_type); 1009 } 1010 1011 void Debugger::PrintAsync(const char *s, size_t len, bool is_stdout) { 1012 lldb::StreamFileSP stream = is_stdout ? GetOutputFile() : GetErrorFile(); 1013 m_input_reader_stack.PrintAsync(stream.get(), s, len); 1014 } 1015 1016 ConstString Debugger::GetTopIOHandlerControlSequence(char ch) { 1017 return m_input_reader_stack.GetTopIOHandlerControlSequence(ch); 1018 } 1019 1020 const char *Debugger::GetIOHandlerCommandPrefix() { 1021 return m_input_reader_stack.GetTopIOHandlerCommandPrefix(); 1022 } 1023 1024 const char *Debugger::GetIOHandlerHelpPrologue() { 1025 return m_input_reader_stack.GetTopIOHandlerHelpPrologue(); 1026 } 1027 1028 void Debugger::RunIOHandler(const IOHandlerSP &reader_sp) { 1029 PushIOHandler(reader_sp); 1030 1031 IOHandlerSP top_reader_sp = reader_sp; 1032 while (top_reader_sp) { 1033 top_reader_sp->Run(); 1034 1035 if (top_reader_sp.get() == reader_sp.get()) { 1036 if (PopIOHandler(reader_sp)) 1037 break; 1038 } 1039 1040 while (true) { 1041 top_reader_sp = m_input_reader_stack.Top(); 1042 if (top_reader_sp && top_reader_sp->GetIsDone()) 1043 PopIOHandler(top_reader_sp); 1044 else 1045 break; 1046 } 1047 } 1048 } 1049 1050 void Debugger::AdoptTopIOHandlerFilesIfInvalid(StreamFileSP &in, 1051 StreamFileSP &out, 1052 StreamFileSP &err) { 1053 // Before an IOHandler runs, it must have in/out/err streams. This function 1054 // is called when one ore more of the streams are nullptr. We use the top 1055 // input reader's in/out/err streams, or fall back to the debugger file 1056 // handles, or we fall back onto stdin/stdout/stderr as a last resort. 1057 1058 std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex()); 1059 IOHandlerSP top_reader_sp(m_input_reader_stack.Top()); 1060 // If no STDIN has been set, then set it appropriately 1061 if (!in) { 1062 if (top_reader_sp) 1063 in = top_reader_sp->GetInputStreamFile(); 1064 else 1065 in = GetInputFile(); 1066 1067 // If there is nothing, use stdin 1068 if (!in) 1069 in = std::make_shared<StreamFile>(stdin, false); 1070 } 1071 // If no STDOUT has been set, then set it appropriately 1072 if (!out) { 1073 if (top_reader_sp) 1074 out = top_reader_sp->GetOutputStreamFile(); 1075 else 1076 out = GetOutputFile(); 1077 1078 // If there is nothing, use stdout 1079 if (!out) 1080 out = std::make_shared<StreamFile>(stdout, false); 1081 } 1082 // If no STDERR has been set, then set it appropriately 1083 if (!err) { 1084 if (top_reader_sp) 1085 err = top_reader_sp->GetErrorStreamFile(); 1086 else 1087 err = GetErrorFile(); 1088 1089 // If there is nothing, use stderr 1090 if (!err) 1091 err = std::make_shared<StreamFile>(stdout, false); 1092 } 1093 } 1094 1095 void Debugger::PushIOHandler(const IOHandlerSP &reader_sp, 1096 bool cancel_top_handler) { 1097 if (!reader_sp) 1098 return; 1099 1100 std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex()); 1101 1102 // Get the current top input reader... 1103 IOHandlerSP top_reader_sp(m_input_reader_stack.Top()); 1104 1105 // Don't push the same IO handler twice... 1106 if (reader_sp == top_reader_sp) 1107 return; 1108 1109 // Push our new input reader 1110 m_input_reader_stack.Push(reader_sp); 1111 reader_sp->Activate(); 1112 1113 // Interrupt the top input reader to it will exit its Run() function and let 1114 // this new input reader take over 1115 if (top_reader_sp) { 1116 top_reader_sp->Deactivate(); 1117 if (cancel_top_handler) 1118 top_reader_sp->Cancel(); 1119 } 1120 } 1121 1122 bool Debugger::PopIOHandler(const IOHandlerSP &pop_reader_sp) { 1123 if (!pop_reader_sp) 1124 return false; 1125 1126 std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex()); 1127 1128 // The reader on the stop of the stack is done, so let the next read on the 1129 // stack refresh its prompt and if there is one... 1130 if (m_input_reader_stack.IsEmpty()) 1131 return false; 1132 1133 IOHandlerSP reader_sp(m_input_reader_stack.Top()); 1134 1135 if (pop_reader_sp != reader_sp) 1136 return false; 1137 1138 reader_sp->Deactivate(); 1139 reader_sp->Cancel(); 1140 m_input_reader_stack.Pop(); 1141 1142 reader_sp = m_input_reader_stack.Top(); 1143 if (reader_sp) 1144 reader_sp->Activate(); 1145 1146 return true; 1147 } 1148 1149 StreamSP Debugger::GetAsyncOutputStream() { 1150 return std::make_shared<StreamAsynchronousIO>(*this, true); 1151 } 1152 1153 StreamSP Debugger::GetAsyncErrorStream() { 1154 return std::make_shared<StreamAsynchronousIO>(*this, false); 1155 } 1156 1157 size_t Debugger::GetNumDebuggers() { 1158 if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) { 1159 std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr); 1160 return g_debugger_list_ptr->size(); 1161 } 1162 return 0; 1163 } 1164 1165 lldb::DebuggerSP Debugger::GetDebuggerAtIndex(size_t index) { 1166 DebuggerSP debugger_sp; 1167 1168 if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) { 1169 std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr); 1170 if (index < g_debugger_list_ptr->size()) 1171 debugger_sp = g_debugger_list_ptr->at(index); 1172 } 1173 1174 return debugger_sp; 1175 } 1176 1177 DebuggerSP Debugger::FindDebuggerWithID(lldb::user_id_t id) { 1178 DebuggerSP debugger_sp; 1179 1180 if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) { 1181 std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr); 1182 DebuggerList::iterator pos, end = g_debugger_list_ptr->end(); 1183 for (pos = g_debugger_list_ptr->begin(); pos != end; ++pos) { 1184 if ((*pos)->GetID() == id) { 1185 debugger_sp = *pos; 1186 break; 1187 } 1188 } 1189 } 1190 return debugger_sp; 1191 } 1192 1193 bool Debugger::FormatDisassemblerAddress(const FormatEntity::Entry *format, 1194 const SymbolContext *sc, 1195 const SymbolContext *prev_sc, 1196 const ExecutionContext *exe_ctx, 1197 const Address *addr, Stream &s) { 1198 FormatEntity::Entry format_entry; 1199 1200 if (format == nullptr) { 1201 if (exe_ctx != nullptr && exe_ctx->HasTargetScope()) 1202 format = exe_ctx->GetTargetRef().GetDebugger().GetDisassemblyFormat(); 1203 if (format == nullptr) { 1204 FormatEntity::Parse("${addr}: ", format_entry); 1205 format = &format_entry; 1206 } 1207 } 1208 bool function_changed = false; 1209 bool initial_function = false; 1210 if (prev_sc && (prev_sc->function || prev_sc->symbol)) { 1211 if (sc && (sc->function || sc->symbol)) { 1212 if (prev_sc->symbol && sc->symbol) { 1213 if (!sc->symbol->Compare(prev_sc->symbol->GetName(), 1214 prev_sc->symbol->GetType())) { 1215 function_changed = true; 1216 } 1217 } else if (prev_sc->function && sc->function) { 1218 if (prev_sc->function->GetMangled() != sc->function->GetMangled()) { 1219 function_changed = true; 1220 } 1221 } 1222 } 1223 } 1224 // The first context on a list of instructions will have a prev_sc that has 1225 // no Function or Symbol -- if SymbolContext had an IsValid() method, it 1226 // would return false. But we do get a prev_sc pointer. 1227 if ((sc && (sc->function || sc->symbol)) && prev_sc && 1228 (prev_sc->function == nullptr && prev_sc->symbol == nullptr)) { 1229 initial_function = true; 1230 } 1231 return FormatEntity::Format(*format, s, sc, exe_ctx, addr, nullptr, 1232 function_changed, initial_function); 1233 } 1234 1235 void Debugger::SetLoggingCallback(lldb::LogOutputCallback log_callback, 1236 void *baton) { 1237 // For simplicity's sake, I am not going to deal with how to close down any 1238 // open logging streams, I just redirect everything from here on out to the 1239 // callback. 1240 m_log_callback_stream_sp = 1241 std::make_shared<StreamCallback>(log_callback, baton); 1242 } 1243 1244 bool Debugger::EnableLog(llvm::StringRef channel, 1245 llvm::ArrayRef<const char *> categories, 1246 llvm::StringRef log_file, uint32_t log_options, 1247 llvm::raw_ostream &error_stream) { 1248 const bool should_close = true; 1249 const bool unbuffered = true; 1250 1251 std::shared_ptr<llvm::raw_ostream> log_stream_sp; 1252 if (m_log_callback_stream_sp) { 1253 log_stream_sp = m_log_callback_stream_sp; 1254 // For now when using the callback mode you always get thread & timestamp. 1255 log_options |= 1256 LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_THREAD_NAME; 1257 } else if (log_file.empty()) { 1258 log_stream_sp = std::make_shared<llvm::raw_fd_ostream>( 1259 GetOutputFile()->GetFile().GetDescriptor(), !should_close, unbuffered); 1260 } else { 1261 auto pos = m_log_streams.find(log_file); 1262 if (pos != m_log_streams.end()) 1263 log_stream_sp = pos->second.lock(); 1264 if (!log_stream_sp) { 1265 llvm::sys::fs::OpenFlags flags = llvm::sys::fs::F_Text; 1266 if (log_options & LLDB_LOG_OPTION_APPEND) 1267 flags |= llvm::sys::fs::F_Append; 1268 int FD; 1269 if (std::error_code ec = llvm::sys::fs::openFileForWrite( 1270 log_file, FD, llvm::sys::fs::CD_CreateAlways, flags)) { 1271 error_stream << "Unable to open log file: " << ec.message(); 1272 return false; 1273 } 1274 log_stream_sp = 1275 std::make_shared<llvm::raw_fd_ostream>(FD, should_close, unbuffered); 1276 m_log_streams[log_file] = log_stream_sp; 1277 } 1278 } 1279 assert(log_stream_sp); 1280 1281 if (log_options == 0) 1282 log_options = 1283 LLDB_LOG_OPTION_PREPEND_THREAD_NAME | LLDB_LOG_OPTION_THREADSAFE; 1284 1285 return Log::EnableLogChannel(log_stream_sp, log_options, channel, categories, 1286 error_stream); 1287 } 1288 1289 ScriptInterpreter *Debugger::GetScriptInterpreter(bool can_create) { 1290 std::lock_guard<std::recursive_mutex> locker(m_script_interpreter_mutex); 1291 1292 if (!m_script_interpreter_sp) { 1293 if (!can_create) 1294 return nullptr; 1295 m_script_interpreter_sp = PluginManager::GetScriptInterpreterForLanguage( 1296 GetScriptLanguage(), *this); 1297 } 1298 1299 return m_script_interpreter_sp.get(); 1300 } 1301 1302 SourceManager &Debugger::GetSourceManager() { 1303 if (!m_source_manager_up) 1304 m_source_manager_up = llvm::make_unique<SourceManager>(shared_from_this()); 1305 return *m_source_manager_up; 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_up.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_up.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