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