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