1//===-- Debugger.cpp ------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "lldb/Core/Debugger.h"
10
11#include "lldb/Breakpoint/Breakpoint.h"
12#include "lldb/Core/DebuggerEvents.h"
13#include "lldb/Core/FormatEntity.h"
14#include "lldb/Core/Mangled.h"
15#include "lldb/Core/ModuleList.h"
16#include "lldb/Core/ModuleSpec.h"
17#include "lldb/Core/PluginManager.h"
18#include "lldb/Core/StreamAsynchronousIO.h"
19#include "lldb/DataFormatters/DataVisualization.h"
20#include "lldb/Expression/REPL.h"
21#include "lldb/Host/File.h"
22#include "lldb/Host/FileSystem.h"
23#include "lldb/Host/HostInfo.h"
24#include "lldb/Host/StreamFile.h"
25#include "lldb/Host/Terminal.h"
26#include "lldb/Host/ThreadLauncher.h"
27#include "lldb/Interpreter/CommandInterpreter.h"
28#include "lldb/Interpreter/CommandReturnObject.h"
29#include "lldb/Interpreter/OptionValue.h"
30#include "lldb/Interpreter/OptionValueLanguage.h"
31#include "lldb/Interpreter/OptionValueProperties.h"
32#include "lldb/Interpreter/OptionValueSInt64.h"
33#include "lldb/Interpreter/OptionValueString.h"
34#include "lldb/Interpreter/Property.h"
35#include "lldb/Interpreter/ScriptInterpreter.h"
36#include "lldb/Symbol/Function.h"
37#include "lldb/Symbol/Symbol.h"
38#include "lldb/Symbol/SymbolContext.h"
39#include "lldb/Target/Language.h"
40#include "lldb/Target/Process.h"
41#include "lldb/Target/StructuredDataPlugin.h"
42#include "lldb/Target/Target.h"
43#include "lldb/Target/TargetList.h"
44#include "lldb/Target/Thread.h"
45#include "lldb/Target/ThreadList.h"
46#include "lldb/Utility/AnsiTerminal.h"
47#include "lldb/Utility/Event.h"
48#include "lldb/Utility/LLDBLog.h"
49#include "lldb/Utility/Listener.h"
50#include "lldb/Utility/Log.h"
51#include "lldb/Utility/State.h"
52#include "lldb/Utility/Stream.h"
53#include "lldb/Utility/StreamString.h"
54#include "lldb/lldb-enumerations.h"
55
56#if defined(_WIN32)
57#include "lldb/Host/windows/PosixApi.h"
58#include "lldb/Host/windows/windows.h"
59#endif
60
61#include "llvm/ADT/STLExtras.h"
62#include "llvm/ADT/StringRef.h"
63#include "llvm/ADT/iterator.h"
64#include "llvm/Support/DynamicLibrary.h"
65#include "llvm/Support/FileSystem.h"
66#include "llvm/Support/Process.h"
67#include "llvm/Support/ThreadPool.h"
68#include "llvm/Support/Threading.h"
69#include "llvm/Support/raw_ostream.h"
70
71#include <cstdio>
72#include <cstdlib>
73#include <cstring>
74#include <list>
75#include <memory>
76#include <mutex>
77#include <optional>
78#include <set>
79#include <string>
80#include <system_error>
81
82// Includes for pipe()
83#if defined(_WIN32)
84#include <fcntl.h>
85#include <io.h>
86#else
87#include <unistd.h>
88#endif
89
90namespace lldb_private {
91class Address;
92}
93
94using namespace lldb;
95using namespace lldb_private;
96
97static lldb::user_id_t g_unique_id = 1;
98static size_t g_debugger_event_thread_stack_bytes = 8 * 1024 * 1024;
99
100#pragma mark Static Functions
101
102static std::recursive_mutex *g_debugger_list_mutex_ptr =
103 nullptr; // NOTE: intentional leak to avoid issues with C++ destructor chain
104static Debugger::DebuggerList *g_debugger_list_ptr =
105 nullptr; // NOTE: intentional leak to avoid issues with C++ destructor chain
106static llvm::ThreadPool *g_thread_pool = nullptr;
107
108static constexpr OptionEnumValueElement g_show_disassembly_enum_values[] = {
109 {
110 .value: Debugger::eStopDisassemblyTypeNever,
111 .string_value: "never",
112 .usage: "Never show disassembly when displaying a stop context.",
113 },
114 {
115 .value: Debugger::eStopDisassemblyTypeNoDebugInfo,
116 .string_value: "no-debuginfo",
117 .usage: "Show disassembly when there is no debug information.",
118 },
119 {
120 .value: Debugger::eStopDisassemblyTypeNoSource,
121 .string_value: "no-source",
122 .usage: "Show disassembly when there is no source information, or the source "
123 "file "
124 "is missing when displaying a stop context.",
125 },
126 {
127 .value: Debugger::eStopDisassemblyTypeAlways,
128 .string_value: "always",
129 .usage: "Always show disassembly when displaying a stop context.",
130 },
131};
132
133static constexpr OptionEnumValueElement g_language_enumerators[] = {
134 {
135 .value: eScriptLanguageNone,
136 .string_value: "none",
137 .usage: "Disable scripting languages.",
138 },
139 {
140 .value: eScriptLanguagePython,
141 .string_value: "python",
142 .usage: "Select python as the default scripting language.",
143 },
144 {
145 .value: eScriptLanguageDefault,
146 .string_value: "default",
147 .usage: "Select the lldb default as the default scripting language.",
148 },
149};
150
151static constexpr OptionEnumValueElement g_dwim_print_verbosities[] = {
152 {.value: eDWIMPrintVerbosityNone, .string_value: "none",
153 .usage: "Use no verbosity when running dwim-print."},
154 {.value: eDWIMPrintVerbosityExpression, .string_value: "expression",
155 .usage: "Use partial verbosity when running dwim-print - display a message when "
156 "`expression` evaluation is used."},
157 {.value: eDWIMPrintVerbosityFull, .string_value: "full",
158 .usage: "Use full verbosity when running dwim-print."},
159};
160
161static constexpr OptionEnumValueElement s_stop_show_column_values[] = {
162 {
163 .value: eStopShowColumnAnsiOrCaret,
164 .string_value: "ansi-or-caret",
165 .usage: "Highlight the stop column with ANSI terminal codes when color/ANSI "
166 "mode is enabled; otherwise, fall back to using a text-only caret (^) "
167 "as if \"caret-only\" mode was selected.",
168 },
169 {
170 .value: eStopShowColumnAnsi,
171 .string_value: "ansi",
172 .usage: "Highlight the stop column with ANSI terminal codes when running LLDB "
173 "with color/ANSI enabled.",
174 },
175 {
176 .value: eStopShowColumnCaret,
177 .string_value: "caret",
178 .usage: "Highlight the stop column with a caret character (^) underneath the "
179 "stop column. This method introduces a new line in source listings "
180 "that display thread stop locations.",
181 },
182 {
183 .value: eStopShowColumnNone,
184 .string_value: "none",
185 .usage: "Do not highlight the stop column.",
186 },
187};
188
189#define LLDB_PROPERTIES_debugger
190#include "CoreProperties.inc"
191
192enum {
193#define LLDB_PROPERTIES_debugger
194#include "CorePropertiesEnum.inc"
195};
196
197LoadPluginCallbackType Debugger::g_load_plugin_callback = nullptr;
198
199Status Debugger::SetPropertyValue(const ExecutionContext *exe_ctx,
200 VarSetOperationType op,
201 llvm::StringRef property_path,
202 llvm::StringRef value) {
203 bool is_load_script =
204 (property_path == "target.load-script-from-symbol-file");
205 // These properties might change how we visualize data.
206 bool invalidate_data_vis = (property_path == "escape-non-printables");
207 invalidate_data_vis |=
208 (property_path == "target.max-zero-padding-in-float-format");
209 if (invalidate_data_vis) {
210 DataVisualization::ForceUpdate();
211 }
212
213 TargetSP target_sp;
214 LoadScriptFromSymFile load_script_old_value = eLoadScriptFromSymFileFalse;
215 if (is_load_script && exe_ctx && exe_ctx->GetTargetSP()) {
216 target_sp = exe_ctx->GetTargetSP();
217 load_script_old_value =
218 target_sp->TargetProperties::GetLoadScriptFromSymbolFile();
219 }
220 Status error(Properties::SetPropertyValue(exe_ctx, op, property_path, value));
221 if (error.Success()) {
222 // FIXME it would be nice to have "on-change" callbacks for properties
223 if (property_path == g_debugger_properties[ePropertyPrompt].name) {
224 llvm::StringRef new_prompt = GetPrompt();
225 std::string str = lldb_private::ansi::FormatAnsiTerminalCodes(
226 format: new_prompt, do_color: GetUseColor());
227 if (str.length())
228 new_prompt = str;
229 GetCommandInterpreter().UpdatePrompt(prompt: new_prompt);
230 auto bytes = std::make_unique<EventDataBytes>(args&: new_prompt);
231 auto prompt_change_event_sp = std::make_shared<Event>(
232 args: CommandInterpreter::eBroadcastBitResetPrompt, args: bytes.release());
233 GetCommandInterpreter().BroadcastEvent(event_sp&: prompt_change_event_sp);
234 } else if (property_path == g_debugger_properties[ePropertyUseColor].name) {
235 // use-color changed. Ping the prompt so it can reset the ansi terminal
236 // codes.
237 SetPrompt(GetPrompt());
238 } else if (property_path ==
239 g_debugger_properties[ePropertyPromptAnsiPrefix].name ||
240 property_path ==
241 g_debugger_properties[ePropertyPromptAnsiSuffix].name) {
242 // Prompt colors changed. Ping the prompt so it can reset the ansi
243 // terminal codes.
244 SetPrompt(GetPrompt());
245 } else if (property_path ==
246 g_debugger_properties[ePropertyUseSourceCache].name) {
247 // use-source-cache changed. Wipe out the cache contents if it was
248 // disabled.
249 if (!GetUseSourceCache()) {
250 m_source_file_cache.Clear();
251 }
252 } else if (is_load_script && target_sp &&
253 load_script_old_value == eLoadScriptFromSymFileWarn) {
254 if (target_sp->TargetProperties::GetLoadScriptFromSymbolFile() ==
255 eLoadScriptFromSymFileTrue) {
256 std::list<Status> errors;
257 StreamString feedback_stream;
258 if (!target_sp->LoadScriptingResources(errors, feedback_stream)) {
259 Stream &s = GetErrorStream();
260 for (auto error : errors) {
261 s.Printf(format: "%s\n", error.AsCString());
262 }
263 if (feedback_stream.GetSize())
264 s.PutCString(cstr: feedback_stream.GetString());
265 }
266 }
267 }
268 }
269 return error;
270}
271
272bool Debugger::GetAutoConfirm() const {
273 constexpr uint32_t idx = ePropertyAutoConfirm;
274 return GetPropertyAtIndexAs<bool>(
275 idx, g_debugger_properties[idx].default_uint_value != 0);
276}
277
278const FormatEntity::Entry *Debugger::GetDisassemblyFormat() const {
279 constexpr uint32_t idx = ePropertyDisassemblyFormat;
280 return GetPropertyAtIndexAs<const FormatEntity::Entry *>(idx);
281}
282
283const FormatEntity::Entry *Debugger::GetFrameFormat() const {
284 constexpr uint32_t idx = ePropertyFrameFormat;
285 return GetPropertyAtIndexAs<const FormatEntity::Entry *>(idx);
286}
287
288const FormatEntity::Entry *Debugger::GetFrameFormatUnique() const {
289 constexpr uint32_t idx = ePropertyFrameFormatUnique;
290 return GetPropertyAtIndexAs<const FormatEntity::Entry *>(idx);
291}
292
293uint64_t Debugger::GetStopDisassemblyMaxSize() const {
294 constexpr uint32_t idx = ePropertyStopDisassemblyMaxSize;
295 return GetPropertyAtIndexAs<uint64_t>(
296 idx, g_debugger_properties[idx].default_uint_value);
297}
298
299bool Debugger::GetNotifyVoid() const {
300 constexpr uint32_t idx = ePropertyNotiftVoid;
301 return GetPropertyAtIndexAs<uint64_t>(
302 idx, g_debugger_properties[idx].default_uint_value != 0);
303}
304
305llvm::StringRef Debugger::GetPrompt() const {
306 constexpr uint32_t idx = ePropertyPrompt;
307 return GetPropertyAtIndexAs<llvm::StringRef>(
308 idx, g_debugger_properties[idx].default_cstr_value);
309}
310
311llvm::StringRef Debugger::GetPromptAnsiPrefix() const {
312 const uint32_t idx = ePropertyPromptAnsiPrefix;
313 return GetPropertyAtIndexAs<llvm::StringRef>(
314 idx, g_debugger_properties[idx].default_cstr_value);
315}
316
317llvm::StringRef Debugger::GetPromptAnsiSuffix() const {
318 const uint32_t idx = ePropertyPromptAnsiSuffix;
319 return GetPropertyAtIndexAs<llvm::StringRef>(
320 idx, g_debugger_properties[idx].default_cstr_value);
321}
322
323void Debugger::SetPrompt(llvm::StringRef p) {
324 constexpr uint32_t idx = ePropertyPrompt;
325 SetPropertyAtIndex(idx, t: p);
326 llvm::StringRef new_prompt = GetPrompt();
327 std::string str =
328 lldb_private::ansi::FormatAnsiTerminalCodes(format: new_prompt, do_color: GetUseColor());
329 if (str.length())
330 new_prompt = str;
331 GetCommandInterpreter().UpdatePrompt(prompt: new_prompt);
332}
333
334const FormatEntity::Entry *Debugger::GetThreadFormat() const {
335 constexpr uint32_t idx = ePropertyThreadFormat;
336 return GetPropertyAtIndexAs<const FormatEntity::Entry *>(idx);
337}
338
339const FormatEntity::Entry *Debugger::GetThreadStopFormat() const {
340 constexpr uint32_t idx = ePropertyThreadStopFormat;
341 return GetPropertyAtIndexAs<const FormatEntity::Entry *>(idx);
342}
343
344lldb::ScriptLanguage Debugger::GetScriptLanguage() const {
345 const uint32_t idx = ePropertyScriptLanguage;
346 return GetPropertyAtIndexAs<lldb::ScriptLanguage>(
347 idx, static_cast<lldb::ScriptLanguage>(
348 g_debugger_properties[idx].default_uint_value));
349}
350
351bool Debugger::SetScriptLanguage(lldb::ScriptLanguage script_lang) {
352 const uint32_t idx = ePropertyScriptLanguage;
353 return SetPropertyAtIndex(idx, t: script_lang);
354}
355
356lldb::LanguageType Debugger::GetREPLLanguage() const {
357 const uint32_t idx = ePropertyREPLLanguage;
358 return GetPropertyAtIndexAs<LanguageType>(idx, default_value: {});
359}
360
361bool Debugger::SetREPLLanguage(lldb::LanguageType repl_lang) {
362 const uint32_t idx = ePropertyREPLLanguage;
363 return SetPropertyAtIndex(idx, t: repl_lang);
364}
365
366uint64_t Debugger::GetTerminalWidth() const {
367 const uint32_t idx = ePropertyTerminalWidth;
368 return GetPropertyAtIndexAs<int64_t>(
369 idx, g_debugger_properties[idx].default_uint_value);
370}
371
372bool Debugger::SetTerminalWidth(uint64_t term_width) {
373 if (auto handler_sp = m_io_handler_stack.Top())
374 handler_sp->TerminalSizeChanged();
375
376 const uint32_t idx = ePropertyTerminalWidth;
377 return SetPropertyAtIndex(idx, t: term_width);
378}
379
380bool Debugger::GetUseExternalEditor() const {
381 const uint32_t idx = ePropertyUseExternalEditor;
382 return GetPropertyAtIndexAs<bool>(
383 idx, g_debugger_properties[idx].default_uint_value != 0);
384}
385
386bool Debugger::SetUseExternalEditor(bool b) {
387 const uint32_t idx = ePropertyUseExternalEditor;
388 return SetPropertyAtIndex(idx, t: b);
389}
390
391llvm::StringRef Debugger::GetExternalEditor() const {
392 const uint32_t idx = ePropertyExternalEditor;
393 return GetPropertyAtIndexAs<llvm::StringRef>(
394 idx, g_debugger_properties[idx].default_cstr_value);
395}
396
397bool Debugger::SetExternalEditor(llvm::StringRef editor) {
398 const uint32_t idx = ePropertyExternalEditor;
399 return SetPropertyAtIndex(idx, t: editor);
400}
401
402bool Debugger::GetUseColor() const {
403 const uint32_t idx = ePropertyUseColor;
404 return GetPropertyAtIndexAs<bool>(
405 idx, g_debugger_properties[idx].default_uint_value != 0);
406}
407
408bool Debugger::SetUseColor(bool b) {
409 const uint32_t idx = ePropertyUseColor;
410 bool ret = SetPropertyAtIndex(idx, t: b);
411 SetPrompt(GetPrompt());
412 return ret;
413}
414
415bool Debugger::GetShowProgress() const {
416 const uint32_t idx = ePropertyShowProgress;
417 return GetPropertyAtIndexAs<bool>(
418 idx, g_debugger_properties[idx].default_uint_value != 0);
419}
420
421bool Debugger::SetShowProgress(bool show_progress) {
422 const uint32_t idx = ePropertyShowProgress;
423 return SetPropertyAtIndex(idx, t: show_progress);
424}
425
426llvm::StringRef Debugger::GetShowProgressAnsiPrefix() const {
427 const uint32_t idx = ePropertyShowProgressAnsiPrefix;
428 return GetPropertyAtIndexAs<llvm::StringRef>(
429 idx, g_debugger_properties[idx].default_cstr_value);
430}
431
432llvm::StringRef Debugger::GetShowProgressAnsiSuffix() const {
433 const uint32_t idx = ePropertyShowProgressAnsiSuffix;
434 return GetPropertyAtIndexAs<llvm::StringRef>(
435 idx, g_debugger_properties[idx].default_cstr_value);
436}
437
438bool Debugger::GetUseAutosuggestion() const {
439 const uint32_t idx = ePropertyShowAutosuggestion;
440 return GetPropertyAtIndexAs<bool>(
441 idx, g_debugger_properties[idx].default_uint_value != 0);
442}
443
444llvm::StringRef Debugger::GetAutosuggestionAnsiPrefix() const {
445 const uint32_t idx = ePropertyShowAutosuggestionAnsiPrefix;
446 return GetPropertyAtIndexAs<llvm::StringRef>(
447 idx, g_debugger_properties[idx].default_cstr_value);
448}
449
450llvm::StringRef Debugger::GetAutosuggestionAnsiSuffix() const {
451 const uint32_t idx = ePropertyShowAutosuggestionAnsiSuffix;
452 return GetPropertyAtIndexAs<llvm::StringRef>(
453 idx, g_debugger_properties[idx].default_cstr_value);
454}
455
456llvm::StringRef Debugger::GetRegexMatchAnsiPrefix() const {
457 const uint32_t idx = ePropertyShowRegexMatchAnsiPrefix;
458 return GetPropertyAtIndexAs<llvm::StringRef>(
459 idx, g_debugger_properties[idx].default_cstr_value);
460}
461
462llvm::StringRef Debugger::GetRegexMatchAnsiSuffix() const {
463 const uint32_t idx = ePropertyShowRegexMatchAnsiSuffix;
464 return GetPropertyAtIndexAs<llvm::StringRef>(
465 idx, g_debugger_properties[idx].default_cstr_value);
466}
467
468bool Debugger::GetShowDontUsePoHint() const {
469 const uint32_t idx = ePropertyShowDontUsePoHint;
470 return GetPropertyAtIndexAs<bool>(
471 idx, g_debugger_properties[idx].default_uint_value != 0);
472}
473
474bool Debugger::GetUseSourceCache() const {
475 const uint32_t idx = ePropertyUseSourceCache;
476 return GetPropertyAtIndexAs<bool>(
477 idx, g_debugger_properties[idx].default_uint_value != 0);
478}
479
480bool Debugger::SetUseSourceCache(bool b) {
481 const uint32_t idx = ePropertyUseSourceCache;
482 bool ret = SetPropertyAtIndex(idx, t: b);
483 if (!ret) {
484 m_source_file_cache.Clear();
485 }
486 return ret;
487}
488bool Debugger::GetHighlightSource() const {
489 const uint32_t idx = ePropertyHighlightSource;
490 return GetPropertyAtIndexAs<bool>(
491 idx, g_debugger_properties[idx].default_uint_value != 0);
492}
493
494StopShowColumn Debugger::GetStopShowColumn() const {
495 const uint32_t idx = ePropertyStopShowColumn;
496 return GetPropertyAtIndexAs<lldb::StopShowColumn>(
497 idx, static_cast<lldb::StopShowColumn>(
498 g_debugger_properties[idx].default_uint_value));
499}
500
501llvm::StringRef Debugger::GetStopShowColumnAnsiPrefix() const {
502 const uint32_t idx = ePropertyStopShowColumnAnsiPrefix;
503 return GetPropertyAtIndexAs<llvm::StringRef>(
504 idx, g_debugger_properties[idx].default_cstr_value);
505}
506
507llvm::StringRef Debugger::GetStopShowColumnAnsiSuffix() const {
508 const uint32_t idx = ePropertyStopShowColumnAnsiSuffix;
509 return GetPropertyAtIndexAs<llvm::StringRef>(
510 idx, g_debugger_properties[idx].default_cstr_value);
511}
512
513llvm::StringRef Debugger::GetStopShowLineMarkerAnsiPrefix() const {
514 const uint32_t idx = ePropertyStopShowLineMarkerAnsiPrefix;
515 return GetPropertyAtIndexAs<llvm::StringRef>(
516 idx, g_debugger_properties[idx].default_cstr_value);
517}
518
519llvm::StringRef Debugger::GetStopShowLineMarkerAnsiSuffix() const {
520 const uint32_t idx = ePropertyStopShowLineMarkerAnsiSuffix;
521 return GetPropertyAtIndexAs<llvm::StringRef>(
522 idx, g_debugger_properties[idx].default_cstr_value);
523}
524
525uint64_t Debugger::GetStopSourceLineCount(bool before) const {
526 const uint32_t idx =
527 before ? ePropertyStopLineCountBefore : ePropertyStopLineCountAfter;
528 return GetPropertyAtIndexAs<uint64_t>(
529 idx, g_debugger_properties[idx].default_uint_value);
530}
531
532Debugger::StopDisassemblyType Debugger::GetStopDisassemblyDisplay() const {
533 const uint32_t idx = ePropertyStopDisassemblyDisplay;
534 return GetPropertyAtIndexAs<Debugger::StopDisassemblyType>(
535 idx, static_cast<Debugger::StopDisassemblyType>(
536 g_debugger_properties[idx].default_uint_value));
537}
538
539uint64_t Debugger::GetDisassemblyLineCount() const {
540 const uint32_t idx = ePropertyStopDisassemblyCount;
541 return GetPropertyAtIndexAs<uint64_t>(
542 idx, g_debugger_properties[idx].default_uint_value);
543}
544
545bool Debugger::GetAutoOneLineSummaries() const {
546 const uint32_t idx = ePropertyAutoOneLineSummaries;
547 return GetPropertyAtIndexAs<bool>(
548 idx, g_debugger_properties[idx].default_uint_value != 0);
549}
550
551bool Debugger::GetEscapeNonPrintables() const {
552 const uint32_t idx = ePropertyEscapeNonPrintables;
553 return GetPropertyAtIndexAs<bool>(
554 idx, g_debugger_properties[idx].default_uint_value != 0);
555}
556
557bool Debugger::GetAutoIndent() const {
558 const uint32_t idx = ePropertyAutoIndent;
559 return GetPropertyAtIndexAs<bool>(
560 idx, g_debugger_properties[idx].default_uint_value != 0);
561}
562
563bool Debugger::SetAutoIndent(bool b) {
564 const uint32_t idx = ePropertyAutoIndent;
565 return SetPropertyAtIndex(idx, t: b);
566}
567
568bool Debugger::GetPrintDecls() const {
569 const uint32_t idx = ePropertyPrintDecls;
570 return GetPropertyAtIndexAs<bool>(
571 idx, g_debugger_properties[idx].default_uint_value != 0);
572}
573
574bool Debugger::SetPrintDecls(bool b) {
575 const uint32_t idx = ePropertyPrintDecls;
576 return SetPropertyAtIndex(idx, t: b);
577}
578
579uint64_t Debugger::GetTabSize() const {
580 const uint32_t idx = ePropertyTabSize;
581 return GetPropertyAtIndexAs<uint64_t>(
582 idx, g_debugger_properties[idx].default_uint_value);
583}
584
585bool Debugger::SetTabSize(uint64_t tab_size) {
586 const uint32_t idx = ePropertyTabSize;
587 return SetPropertyAtIndex(idx, t: tab_size);
588}
589
590lldb::DWIMPrintVerbosity Debugger::GetDWIMPrintVerbosity() const {
591 const uint32_t idx = ePropertyDWIMPrintVerbosity;
592 return GetPropertyAtIndexAs<lldb::DWIMPrintVerbosity>(
593 idx, static_cast<lldb::DWIMPrintVerbosity>(
594 g_debugger_properties[idx].default_uint_value));
595}
596
597#pragma mark Debugger
598
599// const DebuggerPropertiesSP &
600// Debugger::GetSettings() const
601//{
602// return m_properties_sp;
603//}
604//
605
606void Debugger::Initialize(LoadPluginCallbackType load_plugin_callback) {
607 assert(g_debugger_list_ptr == nullptr &&
608 "Debugger::Initialize called more than once!");
609 g_debugger_list_mutex_ptr = new std::recursive_mutex();
610 g_debugger_list_ptr = new DebuggerList();
611 g_thread_pool = new llvm::ThreadPool(llvm::optimal_concurrency());
612 g_load_plugin_callback = load_plugin_callback;
613}
614
615void Debugger::Terminate() {
616 assert(g_debugger_list_ptr &&
617 "Debugger::Terminate called without a matching Debugger::Initialize!");
618
619 if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) {
620 std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
621 for (const auto &debugger : *g_debugger_list_ptr)
622 debugger->HandleDestroyCallback();
623 }
624
625 if (g_thread_pool) {
626 // The destructor will wait for all the threads to complete.
627 delete g_thread_pool;
628 }
629
630 if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) {
631 // Clear our global list of debugger objects
632 {
633 std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
634 for (const auto &debugger : *g_debugger_list_ptr)
635 debugger->Clear();
636 g_debugger_list_ptr->clear();
637 }
638 }
639}
640
641void Debugger::SettingsInitialize() { Target::SettingsInitialize(); }
642
643void Debugger::SettingsTerminate() { Target::SettingsTerminate(); }
644
645bool Debugger::LoadPlugin(const FileSpec &spec, Status &error) {
646 if (g_load_plugin_callback) {
647 llvm::sys::DynamicLibrary dynlib =
648 g_load_plugin_callback(shared_from_this(), spec, error);
649 if (dynlib.isValid()) {
650 m_loaded_plugins.push_back(x: dynlib);
651 return true;
652 }
653 } else {
654 // The g_load_plugin_callback is registered in SBDebugger::Initialize() and
655 // if the public API layer isn't available (code is linking against all of
656 // the internal LLDB static libraries), then we can't load plugins
657 error.SetErrorString("Public API layer is not available");
658 }
659 return false;
660}
661
662static FileSystem::EnumerateDirectoryResult
663LoadPluginCallback(void *baton, llvm::sys::fs::file_type ft,
664 llvm::StringRef path) {
665 Status error;
666
667 static constexpr llvm::StringLiteral g_dylibext(".dylib");
668 static constexpr llvm::StringLiteral g_solibext(".so");
669
670 if (!baton)
671 return FileSystem::eEnumerateDirectoryResultQuit;
672
673 Debugger *debugger = (Debugger *)baton;
674
675 namespace fs = llvm::sys::fs;
676 // If we have a regular file, a symbolic link or unknown file type, try and
677 // process the file. We must handle unknown as sometimes the directory
678 // enumeration might be enumerating a file system that doesn't have correct
679 // file type information.
680 if (ft == fs::file_type::regular_file || ft == fs::file_type::symlink_file ||
681 ft == fs::file_type::type_unknown) {
682 FileSpec plugin_file_spec(path);
683 FileSystem::Instance().Resolve(file_spec&: plugin_file_spec);
684
685 if (plugin_file_spec.GetFileNameExtension() != g_dylibext &&
686 plugin_file_spec.GetFileNameExtension() != g_solibext) {
687 return FileSystem::eEnumerateDirectoryResultNext;
688 }
689
690 Status plugin_load_error;
691 debugger->LoadPlugin(spec: plugin_file_spec, error&: plugin_load_error);
692
693 return FileSystem::eEnumerateDirectoryResultNext;
694 } else if (ft == fs::file_type::directory_file ||
695 ft == fs::file_type::symlink_file ||
696 ft == fs::file_type::type_unknown) {
697 // Try and recurse into anything that a directory or symbolic link. We must
698 // also do this for unknown as sometimes the directory enumeration might be
699 // enumerating a file system that doesn't have correct file type
700 // information.
701 return FileSystem::eEnumerateDirectoryResultEnter;
702 }
703
704 return FileSystem::eEnumerateDirectoryResultNext;
705}
706
707void Debugger::InstanceInitialize() {
708 const bool find_directories = true;
709 const bool find_files = true;
710 const bool find_other = true;
711 char dir_path[PATH_MAX];
712 if (FileSpec dir_spec = HostInfo::GetSystemPluginDir()) {
713 if (FileSystem::Instance().Exists(file_spec: dir_spec) &&
714 dir_spec.GetPath(path: dir_path, max_path_length: sizeof(dir_path))) {
715 FileSystem::Instance().EnumerateDirectory(path: dir_path, find_directories,
716 find_files, find_other,
717 callback: LoadPluginCallback, callback_baton: this);
718 }
719 }
720
721 if (FileSpec dir_spec = HostInfo::GetUserPluginDir()) {
722 if (FileSystem::Instance().Exists(file_spec: dir_spec) &&
723 dir_spec.GetPath(path: dir_path, max_path_length: sizeof(dir_path))) {
724 FileSystem::Instance().EnumerateDirectory(path: dir_path, find_directories,
725 find_files, find_other,
726 callback: LoadPluginCallback, callback_baton: this);
727 }
728 }
729
730 PluginManager::DebuggerInitialize(debugger&: *this);
731}
732
733DebuggerSP Debugger::CreateInstance(lldb::LogOutputCallback log_callback,
734 void *baton) {
735 DebuggerSP debugger_sp(new Debugger(log_callback, baton));
736 if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) {
737 std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
738 g_debugger_list_ptr->push_back(x: debugger_sp);
739 }
740 debugger_sp->InstanceInitialize();
741 return debugger_sp;
742}
743
744void Debugger::HandleDestroyCallback() {
745 if (m_destroy_callback) {
746 m_destroy_callback(GetID(), m_destroy_callback_baton);
747 m_destroy_callback = nullptr;
748 }
749}
750
751void Debugger::Destroy(DebuggerSP &debugger_sp) {
752 if (!debugger_sp)
753 return;
754
755 debugger_sp->HandleDestroyCallback();
756 CommandInterpreter &cmd_interpreter = debugger_sp->GetCommandInterpreter();
757
758 if (cmd_interpreter.GetSaveSessionOnQuit()) {
759 CommandReturnObject result(debugger_sp->GetUseColor());
760 cmd_interpreter.SaveTranscript(result);
761 if (result.Succeeded())
762 (*debugger_sp->GetAsyncOutputStream()) << result.GetOutputData() << '\n';
763 else
764 (*debugger_sp->GetAsyncErrorStream()) << result.GetErrorData() << '\n';
765 }
766
767 debugger_sp->Clear();
768
769 if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) {
770 std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
771 DebuggerList::iterator pos, end = g_debugger_list_ptr->end();
772 for (pos = g_debugger_list_ptr->begin(); pos != end; ++pos) {
773 if ((*pos).get() == debugger_sp.get()) {
774 g_debugger_list_ptr->erase(position: pos);
775 return;
776 }
777 }
778 }
779}
780
781DebuggerSP
782Debugger::FindDebuggerWithInstanceName(llvm::StringRef instance_name) {
783 if (!g_debugger_list_ptr || !g_debugger_list_mutex_ptr)
784 return DebuggerSP();
785
786 std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
787 for (const DebuggerSP &debugger_sp : *g_debugger_list_ptr) {
788 if (!debugger_sp)
789 continue;
790
791 if (llvm::StringRef(debugger_sp->GetInstanceName()) == instance_name)
792 return debugger_sp;
793 }
794 return DebuggerSP();
795}
796
797TargetSP Debugger::FindTargetWithProcessID(lldb::pid_t pid) {
798 TargetSP target_sp;
799 if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) {
800 std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
801 DebuggerList::iterator pos, end = g_debugger_list_ptr->end();
802 for (pos = g_debugger_list_ptr->begin(); pos != end; ++pos) {
803 target_sp = (*pos)->GetTargetList().FindTargetWithProcessID(pid);
804 if (target_sp)
805 break;
806 }
807 }
808 return target_sp;
809}
810
811TargetSP Debugger::FindTargetWithProcess(Process *process) {
812 TargetSP target_sp;
813 if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) {
814 std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
815 DebuggerList::iterator pos, end = g_debugger_list_ptr->end();
816 for (pos = g_debugger_list_ptr->begin(); pos != end; ++pos) {
817 target_sp = (*pos)->GetTargetList().FindTargetWithProcess(process);
818 if (target_sp)
819 break;
820 }
821 }
822 return target_sp;
823}
824
825ConstString Debugger::GetStaticBroadcasterClass() {
826 static ConstString class_name("lldb.debugger");
827 return class_name;
828}
829
830Debugger::Debugger(lldb::LogOutputCallback log_callback, void *baton)
831 : UserID(g_unique_id++),
832 Properties(std::make_shared<OptionValueProperties>()),
833 m_input_file_sp(std::make_shared<NativeFile>(stdin, args: false)),
834 m_output_stream_sp(std::make_shared<StreamFile>(stdout, args: false)),
835 m_error_stream_sp(std::make_shared<StreamFile>(stderr, args: false)),
836 m_input_recorder(nullptr),
837 m_broadcaster_manager_sp(BroadcasterManager::MakeBroadcasterManager()),
838 m_terminal_state(), m_target_list(*this), m_platform_list(),
839 m_listener_sp(Listener::MakeListener(name: "lldb.Debugger")),
840 m_source_manager_up(), m_source_file_cache(),
841 m_command_interpreter_up(
842 std::make_unique<CommandInterpreter>(args&: *this, args: false)),
843 m_io_handler_stack(),
844 m_instance_name(llvm::formatv(Fmt: "debugger_{0}", Vals: GetID()).str()),
845 m_loaded_plugins(), m_event_handler_thread(), m_io_handler_thread(),
846 m_sync_broadcaster(nullptr, "lldb.debugger.sync"),
847 m_broadcaster(m_broadcaster_manager_sp,
848 GetStaticBroadcasterClass().AsCString()),
849 m_forward_listener_sp(), m_clear_once() {
850 // Initialize the debugger properties as early as possible as other parts of
851 // LLDB will start querying them during construction.
852 m_collection_sp->Initialize(g_debugger_properties);
853 m_collection_sp->AppendProperty(
854 name: "target", desc: "Settings specify to debugging targets.", is_global: true,
855 value_sp: Target::GetGlobalProperties().GetValueProperties());
856 m_collection_sp->AppendProperty(
857 name: "platform", desc: "Platform settings.", is_global: true,
858 value_sp: Platform::GetGlobalPlatformProperties().GetValueProperties());
859 m_collection_sp->AppendProperty(
860 name: "symbols", desc: "Symbol lookup and cache settings.", is_global: true,
861 value_sp: ModuleList::GetGlobalModuleListProperties().GetValueProperties());
862 if (m_command_interpreter_up) {
863 m_collection_sp->AppendProperty(
864 name: "interpreter",
865 desc: "Settings specify to the debugger's command interpreter.", is_global: true,
866 value_sp: m_command_interpreter_up->GetValueProperties());
867 }
868 if (log_callback)
869 m_callback_handler_sp =
870 std::make_shared<CallbackLogHandler>(args&: log_callback, args&: baton);
871 m_command_interpreter_up->Initialize();
872 // Always add our default platform to the platform list
873 PlatformSP default_platform_sp(Platform::GetHostPlatform());
874 assert(default_platform_sp);
875 m_platform_list.Append(platform_sp: default_platform_sp, set_selected: true);
876
877 // Create the dummy target.
878 {
879 ArchSpec arch(Target::GetDefaultArchitecture());
880 if (!arch.IsValid())
881 arch = HostInfo::GetArchitecture();
882 assert(arch.IsValid() && "No valid default or host archspec");
883 const bool is_dummy_target = true;
884 m_dummy_target_sp.reset(
885 p: new Target(*this, arch, default_platform_sp, is_dummy_target));
886 }
887 assert(m_dummy_target_sp.get() && "Couldn't construct dummy target?");
888
889 OptionValueSInt64 *term_width =
890 m_collection_sp->GetPropertyAtIndexAsOptionValueSInt64(
891 ePropertyTerminalWidth);
892 term_width->SetMinimumValue(10);
893 term_width->SetMaximumValue(1024);
894
895 // Turn off use-color if this is a dumb terminal.
896 const char *term = getenv(name: "TERM");
897 if (term && !strcmp(s1: term, s2: "dumb"))
898 SetUseColor(false);
899 // Turn off use-color if we don't write to a terminal with color support.
900 if (!GetOutputFile().GetIsTerminalWithColors())
901 SetUseColor(false);
902
903 if (Diagnostics::Enabled()) {
904 m_diagnostics_callback_id = Diagnostics::Instance().AddCallback(
905 callback: [this](const FileSpec &dir) -> llvm::Error {
906 for (auto &entry : m_stream_handlers) {
907 llvm::StringRef log_path = entry.first();
908 llvm::StringRef file_name = llvm::sys::path::filename(path: log_path);
909 FileSpec destination = dir.CopyByAppendingPathComponent(component: file_name);
910 std::error_code ec =
911 llvm::sys::fs::copy_file(From: log_path, To: destination.GetPath());
912 if (ec)
913 return llvm::errorCodeToError(EC: ec);
914 }
915 return llvm::Error::success();
916 });
917 }
918
919#if defined(_WIN32) && defined(ENABLE_VIRTUAL_TERMINAL_PROCESSING)
920 // Enabling use of ANSI color codes because LLDB is using them to highlight
921 // text.
922 llvm::sys::Process::UseANSIEscapeCodes(true);
923#endif
924}
925
926Debugger::~Debugger() { Clear(); }
927
928void Debugger::Clear() {
929 // Make sure we call this function only once. With the C++ global destructor
930 // chain having a list of debuggers and with code that can be running on
931 // other threads, we need to ensure this doesn't happen multiple times.
932 //
933 // The following functions call Debugger::Clear():
934 // Debugger::~Debugger();
935 // static void Debugger::Destroy(lldb::DebuggerSP &debugger_sp);
936 // static void Debugger::Terminate();
937 llvm::call_once(flag&: m_clear_once, F: [this]() {
938 ClearIOHandlers();
939 StopIOHandlerThread();
940 StopEventHandlerThread();
941 m_listener_sp->Clear();
942 for (TargetSP target_sp : m_target_list.Targets()) {
943 if (target_sp) {
944 if (ProcessSP process_sp = target_sp->GetProcessSP())
945 process_sp->Finalize(destructing: false /* not destructing */);
946 target_sp->Destroy();
947 }
948 }
949 m_broadcaster_manager_sp->Clear();
950
951 // Close the input file _before_ we close the input read communications
952 // class as it does NOT own the input file, our m_input_file does.
953 m_terminal_state.Clear();
954 GetInputFile().Close();
955
956 m_command_interpreter_up->Clear();
957
958 if (Diagnostics::Enabled())
959 Diagnostics::Instance().RemoveCallback(id: m_diagnostics_callback_id);
960 });
961}
962
963bool Debugger::GetAsyncExecution() {
964 return !m_command_interpreter_up->GetSynchronous();
965}
966
967void Debugger::SetAsyncExecution(bool async_execution) {
968 m_command_interpreter_up->SetSynchronous(!async_execution);
969}
970
971repro::DataRecorder *Debugger::GetInputRecorder() { return m_input_recorder; }
972
973static inline int OpenPipe(int fds[2], std::size_t size) {
974#ifdef _WIN32
975 return _pipe(fds, size, O_BINARY);
976#else
977 (void)size;
978 return pipe(pipedes: fds);
979#endif
980}
981
982Status Debugger::SetInputString(const char *data) {
983 Status result;
984 enum PIPES { READ, WRITE }; // Indexes for the read and write fds
985 int fds[2] = {-1, -1};
986
987 if (data == nullptr) {
988 result.SetErrorString("String data is null");
989 return result;
990 }
991
992 size_t size = strlen(s: data);
993 if (size == 0) {
994 result.SetErrorString("String data is empty");
995 return result;
996 }
997
998 if (OpenPipe(fds, size) != 0) {
999 result.SetErrorString(
1000 "can't create pipe file descriptors for LLDB commands");
1001 return result;
1002 }
1003
1004 int r = write(fd: fds[WRITE], buf: data, n: size);
1005 (void)r;
1006 // Close the write end of the pipe, so that the command interpreter will exit
1007 // when it consumes all the data.
1008 llvm::sys::Process::SafelyCloseFileDescriptor(FD: fds[WRITE]);
1009
1010 // Open the read file descriptor as a FILE * that we can return as an input
1011 // handle.
1012 FILE *commands_file = fdopen(fd: fds[READ], modes: "rb");
1013 if (commands_file == nullptr) {
1014 result.SetErrorStringWithFormat("fdopen(%i, \"rb\") failed (errno = %i) "
1015 "when trying to open LLDB commands pipe",
1016 fds[READ], errno);
1017 llvm::sys::Process::SafelyCloseFileDescriptor(FD: fds[READ]);
1018 return result;
1019 }
1020
1021 SetInputFile((FileSP)std::make_shared<NativeFile>(args&: commands_file, args: true));
1022 return result;
1023}
1024
1025void Debugger::SetInputFile(FileSP file_sp) {
1026 assert(file_sp && file_sp->IsValid());
1027 m_input_file_sp = std::move(file_sp);
1028 // Save away the terminal state if that is relevant, so that we can restore
1029 // it in RestoreInputState.
1030 SaveInputTerminalState();
1031}
1032
1033void Debugger::SetOutputFile(FileSP file_sp) {
1034 assert(file_sp && file_sp->IsValid());
1035 m_output_stream_sp = std::make_shared<StreamFile>(args&: file_sp);
1036}
1037
1038void Debugger::SetErrorFile(FileSP file_sp) {
1039 assert(file_sp && file_sp->IsValid());
1040 m_error_stream_sp = std::make_shared<StreamFile>(args&: file_sp);
1041}
1042
1043void Debugger::SaveInputTerminalState() {
1044 int fd = GetInputFile().GetDescriptor();
1045 if (fd != File::kInvalidDescriptor)
1046 m_terminal_state.Save(term: fd, save_process_group: true);
1047}
1048
1049void Debugger::RestoreInputTerminalState() { m_terminal_state.Restore(); }
1050
1051ExecutionContext Debugger::GetSelectedExecutionContext() {
1052 bool adopt_selected = true;
1053 ExecutionContextRef exe_ctx_ref(GetSelectedTarget().get(), adopt_selected);
1054 return ExecutionContext(exe_ctx_ref);
1055}
1056
1057void Debugger::DispatchInputInterrupt() {
1058 std::lock_guard<std::recursive_mutex> guard(m_io_handler_stack.GetMutex());
1059 IOHandlerSP reader_sp(m_io_handler_stack.Top());
1060 if (reader_sp)
1061 reader_sp->Interrupt();
1062}
1063
1064void Debugger::DispatchInputEndOfFile() {
1065 std::lock_guard<std::recursive_mutex> guard(m_io_handler_stack.GetMutex());
1066 IOHandlerSP reader_sp(m_io_handler_stack.Top());
1067 if (reader_sp)
1068 reader_sp->GotEOF();
1069}
1070
1071void Debugger::ClearIOHandlers() {
1072 // The bottom input reader should be the main debugger input reader. We do
1073 // not want to close that one here.
1074 std::lock_guard<std::recursive_mutex> guard(m_io_handler_stack.GetMutex());
1075 while (m_io_handler_stack.GetSize() > 1) {
1076 IOHandlerSP reader_sp(m_io_handler_stack.Top());
1077 if (reader_sp)
1078 PopIOHandler(reader_sp);
1079 }
1080}
1081
1082void Debugger::RunIOHandlers() {
1083 IOHandlerSP reader_sp = m_io_handler_stack.Top();
1084 while (true) {
1085 if (!reader_sp)
1086 break;
1087
1088 reader_sp->Run();
1089 {
1090 std::lock_guard<std::recursive_mutex> guard(
1091 m_io_handler_synchronous_mutex);
1092
1093 // Remove all input readers that are done from the top of the stack
1094 while (true) {
1095 IOHandlerSP top_reader_sp = m_io_handler_stack.Top();
1096 if (top_reader_sp && top_reader_sp->GetIsDone())
1097 PopIOHandler(reader_sp: top_reader_sp);
1098 else
1099 break;
1100 }
1101 reader_sp = m_io_handler_stack.Top();
1102 }
1103 }
1104 ClearIOHandlers();
1105}
1106
1107void Debugger::RunIOHandlerSync(const IOHandlerSP &reader_sp) {
1108 std::lock_guard<std::recursive_mutex> guard(m_io_handler_synchronous_mutex);
1109
1110 PushIOHandler(reader_sp);
1111 IOHandlerSP top_reader_sp = reader_sp;
1112
1113 while (top_reader_sp) {
1114 if (!top_reader_sp)
1115 break;
1116
1117 top_reader_sp->Run();
1118
1119 // Don't unwind past the starting point.
1120 if (top_reader_sp.get() == reader_sp.get()) {
1121 if (PopIOHandler(reader_sp))
1122 break;
1123 }
1124
1125 // If we pushed new IO handlers, pop them if they're done or restart the
1126 // loop to run them if they're not.
1127 while (true) {
1128 top_reader_sp = m_io_handler_stack.Top();
1129 if (top_reader_sp && top_reader_sp->GetIsDone()) {
1130 PopIOHandler(reader_sp: top_reader_sp);
1131 // Don't unwind past the starting point.
1132 if (top_reader_sp.get() == reader_sp.get())
1133 return;
1134 } else {
1135 break;
1136 }
1137 }
1138 }
1139}
1140
1141bool Debugger::IsTopIOHandler(const lldb::IOHandlerSP &reader_sp) {
1142 return m_io_handler_stack.IsTop(io_handler_sp: reader_sp);
1143}
1144
1145bool Debugger::CheckTopIOHandlerTypes(IOHandler::Type top_type,
1146 IOHandler::Type second_top_type) {
1147 return m_io_handler_stack.CheckTopIOHandlerTypes(top_type, second_top_type);
1148}
1149
1150void Debugger::PrintAsync(const char *s, size_t len, bool is_stdout) {
1151 bool printed = m_io_handler_stack.PrintAsync(s, len, is_stdout);
1152 if (!printed) {
1153 lldb::StreamFileSP stream =
1154 is_stdout ? m_output_stream_sp : m_error_stream_sp;
1155 stream->Write(src: s, src_len: len);
1156 }
1157}
1158
1159llvm::StringRef Debugger::GetTopIOHandlerControlSequence(char ch) {
1160 return m_io_handler_stack.GetTopIOHandlerControlSequence(ch);
1161}
1162
1163const char *Debugger::GetIOHandlerCommandPrefix() {
1164 return m_io_handler_stack.GetTopIOHandlerCommandPrefix();
1165}
1166
1167const char *Debugger::GetIOHandlerHelpPrologue() {
1168 return m_io_handler_stack.GetTopIOHandlerHelpPrologue();
1169}
1170
1171bool Debugger::RemoveIOHandler(const IOHandlerSP &reader_sp) {
1172 return PopIOHandler(reader_sp);
1173}
1174
1175void Debugger::RunIOHandlerAsync(const IOHandlerSP &reader_sp,
1176 bool cancel_top_handler) {
1177 PushIOHandler(reader_sp, cancel_top_handler);
1178}
1179
1180void Debugger::AdoptTopIOHandlerFilesIfInvalid(FileSP &in, StreamFileSP &out,
1181 StreamFileSP &err) {
1182 // Before an IOHandler runs, it must have in/out/err streams. This function
1183 // is called when one ore more of the streams are nullptr. We use the top
1184 // input reader's in/out/err streams, or fall back to the debugger file
1185 // handles, or we fall back onto stdin/stdout/stderr as a last resort.
1186
1187 std::lock_guard<std::recursive_mutex> guard(m_io_handler_stack.GetMutex());
1188 IOHandlerSP top_reader_sp(m_io_handler_stack.Top());
1189 // If no STDIN has been set, then set it appropriately
1190 if (!in || !in->IsValid()) {
1191 if (top_reader_sp)
1192 in = top_reader_sp->GetInputFileSP();
1193 else
1194 in = GetInputFileSP();
1195 // If there is nothing, use stdin
1196 if (!in)
1197 in = std::make_shared<NativeFile>(stdin, args: false);
1198 }
1199 // If no STDOUT has been set, then set it appropriately
1200 if (!out || !out->GetFile().IsValid()) {
1201 if (top_reader_sp)
1202 out = top_reader_sp->GetOutputStreamFileSP();
1203 else
1204 out = GetOutputStreamSP();
1205 // If there is nothing, use stdout
1206 if (!out)
1207 out = std::make_shared<StreamFile>(stdout, args: false);
1208 }
1209 // If no STDERR has been set, then set it appropriately
1210 if (!err || !err->GetFile().IsValid()) {
1211 if (top_reader_sp)
1212 err = top_reader_sp->GetErrorStreamFileSP();
1213 else
1214 err = GetErrorStreamSP();
1215 // If there is nothing, use stderr
1216 if (!err)
1217 err = std::make_shared<StreamFile>(stderr, args: false);
1218 }
1219}
1220
1221void Debugger::PushIOHandler(const IOHandlerSP &reader_sp,
1222 bool cancel_top_handler) {
1223 if (!reader_sp)
1224 return;
1225
1226 std::lock_guard<std::recursive_mutex> guard(m_io_handler_stack.GetMutex());
1227
1228 // Get the current top input reader...
1229 IOHandlerSP top_reader_sp(m_io_handler_stack.Top());
1230
1231 // Don't push the same IO handler twice...
1232 if (reader_sp == top_reader_sp)
1233 return;
1234
1235 // Push our new input reader
1236 m_io_handler_stack.Push(sp: reader_sp);
1237 reader_sp->Activate();
1238
1239 // Interrupt the top input reader to it will exit its Run() function and let
1240 // this new input reader take over
1241 if (top_reader_sp) {
1242 top_reader_sp->Deactivate();
1243 if (cancel_top_handler)
1244 top_reader_sp->Cancel();
1245 }
1246}
1247
1248bool Debugger::PopIOHandler(const IOHandlerSP &pop_reader_sp) {
1249 if (!pop_reader_sp)
1250 return false;
1251
1252 std::lock_guard<std::recursive_mutex> guard(m_io_handler_stack.GetMutex());
1253
1254 // The reader on the stop of the stack is done, so let the next read on the
1255 // stack refresh its prompt and if there is one...
1256 if (m_io_handler_stack.IsEmpty())
1257 return false;
1258
1259 IOHandlerSP reader_sp(m_io_handler_stack.Top());
1260
1261 if (pop_reader_sp != reader_sp)
1262 return false;
1263
1264 reader_sp->Deactivate();
1265 reader_sp->Cancel();
1266 m_io_handler_stack.Pop();
1267
1268 reader_sp = m_io_handler_stack.Top();
1269 if (reader_sp)
1270 reader_sp->Activate();
1271
1272 return true;
1273}
1274
1275StreamSP Debugger::GetAsyncOutputStream() {
1276 return std::make_shared<StreamAsynchronousIO>(args&: *this, args: true, args: GetUseColor());
1277}
1278
1279StreamSP Debugger::GetAsyncErrorStream() {
1280 return std::make_shared<StreamAsynchronousIO>(args&: *this, args: false, args: GetUseColor());
1281}
1282
1283void Debugger::RequestInterrupt() {
1284 std::lock_guard<std::mutex> guard(m_interrupt_mutex);
1285 m_interrupt_requested++;
1286}
1287
1288void Debugger::CancelInterruptRequest() {
1289 std::lock_guard<std::mutex> guard(m_interrupt_mutex);
1290 if (m_interrupt_requested > 0)
1291 m_interrupt_requested--;
1292}
1293
1294bool Debugger::InterruptRequested() {
1295 // This is the one we should call internally. This will return true either
1296 // if there's a debugger interrupt and we aren't on the IOHandler thread,
1297 // or if we are on the IOHandler thread and there's a CommandInterpreter
1298 // interrupt.
1299 if (!IsIOHandlerThreadCurrentThread()) {
1300 std::lock_guard<std::mutex> guard(m_interrupt_mutex);
1301 return m_interrupt_requested != 0;
1302 }
1303 return GetCommandInterpreter().WasInterrupted();
1304}
1305
1306Debugger::InterruptionReport::InterruptionReport(
1307 std::string function_name, const llvm::formatv_object_base &payload)
1308 : m_function_name(std::move(function_name)),
1309 m_interrupt_time(std::chrono::system_clock::now()),
1310 m_thread_id(llvm::get_threadid()) {
1311 llvm::raw_string_ostream desc(m_description);
1312 desc << payload << "\n";
1313}
1314
1315void Debugger::ReportInterruption(const InterruptionReport &report) {
1316 // For now, just log the description:
1317 Log *log = GetLog(mask: LLDBLog::Host);
1318 LLDB_LOG(log, "Interruption: {0}", report.m_description);
1319}
1320
1321Debugger::DebuggerList Debugger::DebuggersRequestingInterruption() {
1322 DebuggerList result;
1323 if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) {
1324 std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
1325 for (auto debugger_sp : *g_debugger_list_ptr) {
1326 if (debugger_sp->InterruptRequested())
1327 result.push_back(x: debugger_sp);
1328 }
1329 }
1330 return result;
1331}
1332
1333size_t Debugger::GetNumDebuggers() {
1334 if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) {
1335 std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
1336 return g_debugger_list_ptr->size();
1337 }
1338 return 0;
1339}
1340
1341lldb::DebuggerSP Debugger::GetDebuggerAtIndex(size_t index) {
1342 DebuggerSP debugger_sp;
1343
1344 if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) {
1345 std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
1346 if (index < g_debugger_list_ptr->size())
1347 debugger_sp = g_debugger_list_ptr->at(n: index);
1348 }
1349
1350 return debugger_sp;
1351}
1352
1353DebuggerSP Debugger::FindDebuggerWithID(lldb::user_id_t id) {
1354 DebuggerSP debugger_sp;
1355
1356 if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) {
1357 std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
1358 DebuggerList::iterator pos, end = g_debugger_list_ptr->end();
1359 for (pos = g_debugger_list_ptr->begin(); pos != end; ++pos) {
1360 if ((*pos)->GetID() == id) {
1361 debugger_sp = *pos;
1362 break;
1363 }
1364 }
1365 }
1366 return debugger_sp;
1367}
1368
1369bool Debugger::FormatDisassemblerAddress(const FormatEntity::Entry *format,
1370 const SymbolContext *sc,
1371 const SymbolContext *prev_sc,
1372 const ExecutionContext *exe_ctx,
1373 const Address *addr, Stream &s) {
1374 FormatEntity::Entry format_entry;
1375
1376 if (format == nullptr) {
1377 if (exe_ctx != nullptr && exe_ctx->HasTargetScope())
1378 format = exe_ctx->GetTargetRef().GetDebugger().GetDisassemblyFormat();
1379 if (format == nullptr) {
1380 FormatEntity::Parse(format: "${addr}: ", entry&: format_entry);
1381 format = &format_entry;
1382 }
1383 }
1384 bool function_changed = false;
1385 bool initial_function = false;
1386 if (prev_sc && (prev_sc->function || prev_sc->symbol)) {
1387 if (sc && (sc->function || sc->symbol)) {
1388 if (prev_sc->symbol && sc->symbol) {
1389 if (!sc->symbol->Compare(name: prev_sc->symbol->GetName(),
1390 type: prev_sc->symbol->GetType())) {
1391 function_changed = true;
1392 }
1393 } else if (prev_sc->function && sc->function) {
1394 if (prev_sc->function->GetMangled() != sc->function->GetMangled()) {
1395 function_changed = true;
1396 }
1397 }
1398 }
1399 }
1400 // The first context on a list of instructions will have a prev_sc that has
1401 // no Function or Symbol -- if SymbolContext had an IsValid() method, it
1402 // would return false. But we do get a prev_sc pointer.
1403 if ((sc && (sc->function || sc->symbol)) && prev_sc &&
1404 (prev_sc->function == nullptr && prev_sc->symbol == nullptr)) {
1405 initial_function = true;
1406 }
1407 return FormatEntity::Format(entry: *format, s, sc, exe_ctx, addr, valobj: nullptr,
1408 function_changed, initial_function);
1409}
1410
1411void Debugger::AssertCallback(llvm::StringRef message,
1412 llvm::StringRef backtrace,
1413 llvm::StringRef prompt) {
1414 Debugger::ReportError(
1415 message: llvm::formatv(Fmt: "{0}\n{1}{2}", Vals&: message, Vals&: backtrace, Vals&: prompt).str());
1416}
1417
1418void Debugger::SetLoggingCallback(lldb::LogOutputCallback log_callback,
1419 void *baton) {
1420 // For simplicity's sake, I am not going to deal with how to close down any
1421 // open logging streams, I just redirect everything from here on out to the
1422 // callback.
1423 m_callback_handler_sp =
1424 std::make_shared<CallbackLogHandler>(args&: log_callback, args&: baton);
1425}
1426
1427void Debugger::SetDestroyCallback(
1428 lldb_private::DebuggerDestroyCallback destroy_callback, void *baton) {
1429 m_destroy_callback = destroy_callback;
1430 m_destroy_callback_baton = baton;
1431}
1432
1433static void PrivateReportProgress(Debugger &debugger, uint64_t progress_id,
1434 std::string title, std::string details,
1435 uint64_t completed, uint64_t total,
1436 bool is_debugger_specific) {
1437 // Only deliver progress events if we have any progress listeners.
1438 const uint32_t event_type = Debugger::eBroadcastBitProgress;
1439 if (!debugger.GetBroadcaster().EventTypeHasListeners(event_type))
1440 return;
1441 EventSP event_sp(new Event(
1442 event_type,
1443 new ProgressEventData(progress_id, std::move(title), std::move(details),
1444 completed, total, is_debugger_specific)));
1445 debugger.GetBroadcaster().BroadcastEvent(event_sp);
1446}
1447
1448void Debugger::ReportProgress(uint64_t progress_id, std::string title,
1449 std::string details, uint64_t completed,
1450 uint64_t total,
1451 std::optional<lldb::user_id_t> debugger_id) {
1452 // Check if this progress is for a specific debugger.
1453 if (debugger_id) {
1454 // It is debugger specific, grab it and deliver the event if the debugger
1455 // still exists.
1456 DebuggerSP debugger_sp = FindDebuggerWithID(id: *debugger_id);
1457 if (debugger_sp)
1458 PrivateReportProgress(debugger&: *debugger_sp, progress_id, title: std::move(title),
1459 details: std::move(details), completed, total,
1460 /*is_debugger_specific*/ true);
1461 return;
1462 }
1463 // The progress event is not debugger specific, iterate over all debuggers
1464 // and deliver a progress event to each one.
1465 if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) {
1466 std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
1467 DebuggerList::iterator pos, end = g_debugger_list_ptr->end();
1468 for (pos = g_debugger_list_ptr->begin(); pos != end; ++pos)
1469 PrivateReportProgress(debugger&: *(*pos), progress_id, title, details, completed,
1470 total, /*is_debugger_specific*/ false);
1471 }
1472}
1473
1474static void PrivateReportDiagnostic(Debugger &debugger,
1475 DiagnosticEventData::Type type,
1476 std::string message,
1477 bool debugger_specific) {
1478 uint32_t event_type = 0;
1479 switch (type) {
1480 case DiagnosticEventData::Type::Info:
1481 assert(false && "DiagnosticEventData::Type::Info should not be broadcast");
1482 return;
1483 case DiagnosticEventData::Type::Warning:
1484 event_type = Debugger::eBroadcastBitWarning;
1485 break;
1486 case DiagnosticEventData::Type::Error:
1487 event_type = Debugger::eBroadcastBitError;
1488 break;
1489 }
1490
1491 Broadcaster &broadcaster = debugger.GetBroadcaster();
1492 if (!broadcaster.EventTypeHasListeners(event_type)) {
1493 // Diagnostics are too important to drop. If nobody is listening, print the
1494 // diagnostic directly to the debugger's error stream.
1495 DiagnosticEventData event_data(type, std::move(message), debugger_specific);
1496 StreamSP stream = debugger.GetAsyncErrorStream();
1497 event_data.Dump(s: stream.get());
1498 return;
1499 }
1500 EventSP event_sp = std::make_shared<Event>(
1501 args&: event_type,
1502 args: new DiagnosticEventData(type, std::move(message), debugger_specific));
1503 broadcaster.BroadcastEvent(event_sp);
1504}
1505
1506void Debugger::ReportDiagnosticImpl(DiagnosticEventData::Type type,
1507 std::string message,
1508 std::optional<lldb::user_id_t> debugger_id,
1509 std::once_flag *once) {
1510 auto ReportDiagnosticLambda = [&]() {
1511 // The diagnostic subsystem is optional but we still want to broadcast
1512 // events when it's disabled.
1513 if (Diagnostics::Enabled())
1514 Diagnostics::Instance().Report(message);
1515
1516 // We don't broadcast info events.
1517 if (type == DiagnosticEventData::Type::Info)
1518 return;
1519
1520 // Check if this diagnostic is for a specific debugger.
1521 if (debugger_id) {
1522 // It is debugger specific, grab it and deliver the event if the debugger
1523 // still exists.
1524 DebuggerSP debugger_sp = FindDebuggerWithID(id: *debugger_id);
1525 if (debugger_sp)
1526 PrivateReportDiagnostic(debugger&: *debugger_sp, type, message: std::move(message), debugger_specific: true);
1527 return;
1528 }
1529 // The diagnostic event is not debugger specific, iterate over all debuggers
1530 // and deliver a diagnostic event to each one.
1531 if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) {
1532 std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
1533 for (const auto &debugger : *g_debugger_list_ptr)
1534 PrivateReportDiagnostic(debugger&: *debugger, type, message, debugger_specific: false);
1535 }
1536 };
1537
1538 if (once)
1539 std::call_once(once&: *once, f&: ReportDiagnosticLambda);
1540 else
1541 ReportDiagnosticLambda();
1542}
1543
1544void Debugger::ReportWarning(std::string message,
1545 std::optional<lldb::user_id_t> debugger_id,
1546 std::once_flag *once) {
1547 ReportDiagnosticImpl(type: DiagnosticEventData::Type::Warning, message: std::move(message),
1548 debugger_id, once);
1549}
1550
1551void Debugger::ReportError(std::string message,
1552 std::optional<lldb::user_id_t> debugger_id,
1553 std::once_flag *once) {
1554 ReportDiagnosticImpl(type: DiagnosticEventData::Type::Error, message: std::move(message),
1555 debugger_id, once);
1556}
1557
1558void Debugger::ReportInfo(std::string message,
1559 std::optional<lldb::user_id_t> debugger_id,
1560 std::once_flag *once) {
1561 ReportDiagnosticImpl(type: DiagnosticEventData::Type::Info, message: std::move(message),
1562 debugger_id, once);
1563}
1564
1565void Debugger::ReportSymbolChange(const ModuleSpec &module_spec) {
1566 if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) {
1567 std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
1568 for (DebuggerSP debugger_sp : *g_debugger_list_ptr) {
1569 EventSP event_sp = std::make_shared<Event>(
1570 args: Debugger::eBroadcastSymbolChange,
1571 args: new SymbolChangeEventData(debugger_sp, module_spec));
1572 debugger_sp->GetBroadcaster().BroadcastEvent(event_sp);
1573 }
1574 }
1575}
1576
1577static std::shared_ptr<LogHandler>
1578CreateLogHandler(LogHandlerKind log_handler_kind, int fd, bool should_close,
1579 size_t buffer_size) {
1580 switch (log_handler_kind) {
1581 case eLogHandlerStream:
1582 return std::make_shared<StreamLogHandler>(args&: fd, args&: should_close, args&: buffer_size);
1583 case eLogHandlerCircular:
1584 return std::make_shared<RotatingLogHandler>(args&: buffer_size);
1585 case eLogHandlerSystem:
1586 return std::make_shared<SystemLogHandler>();
1587 case eLogHandlerCallback:
1588 return {};
1589 }
1590 return {};
1591}
1592
1593bool Debugger::EnableLog(llvm::StringRef channel,
1594 llvm::ArrayRef<const char *> categories,
1595 llvm::StringRef log_file, uint32_t log_options,
1596 size_t buffer_size, LogHandlerKind log_handler_kind,
1597 llvm::raw_ostream &error_stream) {
1598
1599 std::shared_ptr<LogHandler> log_handler_sp;
1600 if (m_callback_handler_sp) {
1601 log_handler_sp = m_callback_handler_sp;
1602 // For now when using the callback mode you always get thread & timestamp.
1603 log_options |=
1604 LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_THREAD_NAME;
1605 } else if (log_file.empty()) {
1606 log_handler_sp =
1607 CreateLogHandler(log_handler_kind, fd: GetOutputFile().GetDescriptor(),
1608 /*should_close=*/false, buffer_size);
1609 } else {
1610 auto pos = m_stream_handlers.find(Key: log_file);
1611 if (pos != m_stream_handlers.end())
1612 log_handler_sp = pos->second.lock();
1613 if (!log_handler_sp) {
1614 File::OpenOptions flags =
1615 File::eOpenOptionWriteOnly | File::eOpenOptionCanCreate;
1616 if (log_options & LLDB_LOG_OPTION_APPEND)
1617 flags |= File::eOpenOptionAppend;
1618 else
1619 flags |= File::eOpenOptionTruncate;
1620 llvm::Expected<FileUP> file = FileSystem::Instance().Open(
1621 file_spec: FileSpec(log_file), options: flags, permissions: lldb::eFilePermissionsFileDefault, should_close_fd: false);
1622 if (!file) {
1623 error_stream << "Unable to open log file '" << log_file
1624 << "': " << llvm::toString(E: file.takeError()) << "\n";
1625 return false;
1626 }
1627
1628 log_handler_sp =
1629 CreateLogHandler(log_handler_kind, fd: (*file)->GetDescriptor(),
1630 /*should_close=*/true, buffer_size);
1631 m_stream_handlers[log_file] = log_handler_sp;
1632 }
1633 }
1634 assert(log_handler_sp);
1635
1636 if (log_options == 0)
1637 log_options = LLDB_LOG_OPTION_PREPEND_THREAD_NAME;
1638
1639 return Log::EnableLogChannel(log_handler_sp, log_options, channel, categories,
1640 error_stream);
1641}
1642
1643ScriptInterpreter *
1644Debugger::GetScriptInterpreter(bool can_create,
1645 std::optional<lldb::ScriptLanguage> language) {
1646 std::lock_guard<std::recursive_mutex> locker(m_script_interpreter_mutex);
1647 lldb::ScriptLanguage script_language =
1648 language ? *language : GetScriptLanguage();
1649
1650 if (!m_script_interpreters[script_language]) {
1651 if (!can_create)
1652 return nullptr;
1653 m_script_interpreters[script_language] =
1654 PluginManager::GetScriptInterpreterForLanguage(script_lang: script_language, debugger&: *this);
1655 }
1656
1657 return m_script_interpreters[script_language].get();
1658}
1659
1660SourceManager &Debugger::GetSourceManager() {
1661 if (!m_source_manager_up)
1662 m_source_manager_up = std::make_unique<SourceManager>(args: shared_from_this());
1663 return *m_source_manager_up;
1664}
1665
1666// This function handles events that were broadcast by the process.
1667void Debugger::HandleBreakpointEvent(const EventSP &event_sp) {
1668 using namespace lldb;
1669 const uint32_t event_type =
1670 Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent(
1671 event_sp);
1672
1673 // if (event_type & eBreakpointEventTypeAdded
1674 // || event_type & eBreakpointEventTypeRemoved
1675 // || event_type & eBreakpointEventTypeEnabled
1676 // || event_type & eBreakpointEventTypeDisabled
1677 // || event_type & eBreakpointEventTypeCommandChanged
1678 // || event_type & eBreakpointEventTypeConditionChanged
1679 // || event_type & eBreakpointEventTypeIgnoreChanged
1680 // || event_type & eBreakpointEventTypeLocationsResolved)
1681 // {
1682 // // Don't do anything about these events, since the breakpoint
1683 // commands already echo these actions.
1684 // }
1685 //
1686 if (event_type & eBreakpointEventTypeLocationsAdded) {
1687 uint32_t num_new_locations =
1688 Breakpoint::BreakpointEventData::GetNumBreakpointLocationsFromEvent(
1689 event_sp);
1690 if (num_new_locations > 0) {
1691 BreakpointSP breakpoint =
1692 Breakpoint::BreakpointEventData::GetBreakpointFromEvent(event_sp);
1693 StreamSP output_sp(GetAsyncOutputStream());
1694 if (output_sp) {
1695 output_sp->Printf(format: "%d location%s added to breakpoint %d\n",
1696 num_new_locations, num_new_locations == 1 ? "" : "s",
1697 breakpoint->GetID());
1698 output_sp->Flush();
1699 }
1700 }
1701 }
1702 // else if (event_type & eBreakpointEventTypeLocationsRemoved)
1703 // {
1704 // // These locations just get disabled, not sure it is worth spamming
1705 // folks about this on the command line.
1706 // }
1707 // else if (event_type & eBreakpointEventTypeLocationsResolved)
1708 // {
1709 // // This might be an interesting thing to note, but I'm going to
1710 // leave it quiet for now, it just looked noisy.
1711 // }
1712}
1713
1714void Debugger::FlushProcessOutput(Process &process, bool flush_stdout,
1715 bool flush_stderr) {
1716 const auto &flush = [&](Stream &stream,
1717 size_t (Process::*get)(char *, size_t, Status &)) {
1718 Status error;
1719 size_t len;
1720 char buffer[1024];
1721 while ((len = (process.*get)(buffer, sizeof(buffer), error)) > 0)
1722 stream.Write(src: buffer, src_len: len);
1723 stream.Flush();
1724 };
1725
1726 std::lock_guard<std::mutex> guard(m_output_flush_mutex);
1727 if (flush_stdout)
1728 flush(*GetAsyncOutputStream(), &Process::GetSTDOUT);
1729 if (flush_stderr)
1730 flush(*GetAsyncErrorStream(), &Process::GetSTDERR);
1731}
1732
1733// This function handles events that were broadcast by the process.
1734void Debugger::HandleProcessEvent(const EventSP &event_sp) {
1735 using namespace lldb;
1736 const uint32_t event_type = event_sp->GetType();
1737 ProcessSP process_sp =
1738 (event_type == Process::eBroadcastBitStructuredData)
1739 ? EventDataStructuredData::GetProcessFromEvent(event_ptr: event_sp.get())
1740 : Process::ProcessEventData::GetProcessFromEvent(event_ptr: event_sp.get());
1741
1742 StreamSP output_stream_sp = GetAsyncOutputStream();
1743 StreamSP error_stream_sp = GetAsyncErrorStream();
1744 const bool gui_enabled = IsForwardingEvents();
1745
1746 if (!gui_enabled) {
1747 bool pop_process_io_handler = false;
1748 assert(process_sp);
1749
1750 bool state_is_stopped = false;
1751 const bool got_state_changed =
1752 (event_type & Process::eBroadcastBitStateChanged) != 0;
1753 const bool got_stdout = (event_type & Process::eBroadcastBitSTDOUT) != 0;
1754 const bool got_stderr = (event_type & Process::eBroadcastBitSTDERR) != 0;
1755 const bool got_structured_data =
1756 (event_type & Process::eBroadcastBitStructuredData) != 0;
1757
1758 if (got_state_changed) {
1759 StateType event_state =
1760 Process::ProcessEventData::GetStateFromEvent(event_ptr: event_sp.get());
1761 state_is_stopped = StateIsStoppedState(state: event_state, must_exist: false);
1762 }
1763
1764 // Display running state changes first before any STDIO
1765 if (got_state_changed && !state_is_stopped) {
1766 // This is a public stop which we are going to announce to the user, so
1767 // we should force the most relevant frame selection here.
1768 Process::HandleProcessStateChangedEvent(event_sp, stream: output_stream_sp.get(),
1769 select_most_relevant: SelectMostRelevantFrame,
1770 pop_process_io_handler);
1771 }
1772
1773 // Now display STDOUT and STDERR
1774 FlushProcessOutput(process&: *process_sp, flush_stdout: got_stdout || got_state_changed,
1775 flush_stderr: got_stderr || got_state_changed);
1776
1777 // Give structured data events an opportunity to display.
1778 if (got_structured_data) {
1779 StructuredDataPluginSP plugin_sp =
1780 EventDataStructuredData::GetPluginFromEvent(event_ptr: event_sp.get());
1781 if (plugin_sp) {
1782 auto structured_data_sp =
1783 EventDataStructuredData::GetObjectFromEvent(event_ptr: event_sp.get());
1784 if (output_stream_sp) {
1785 StreamString content_stream;
1786 Status error =
1787 plugin_sp->GetDescription(object_sp: structured_data_sp, stream&: content_stream);
1788 if (error.Success()) {
1789 if (!content_stream.GetString().empty()) {
1790 // Add newline.
1791 content_stream.PutChar(ch: '\n');
1792 content_stream.Flush();
1793
1794 // Print it.
1795 output_stream_sp->PutCString(cstr: content_stream.GetString());
1796 }
1797 } else {
1798 error_stream_sp->Format(format: "Failed to print structured "
1799 "data with plugin {0}: {1}",
1800 args: plugin_sp->GetPluginName(), args&: error);
1801 }
1802 }
1803 }
1804 }
1805
1806 // Now display any stopped state changes after any STDIO
1807 if (got_state_changed && state_is_stopped) {
1808 Process::HandleProcessStateChangedEvent(event_sp, stream: output_stream_sp.get(),
1809 select_most_relevant: SelectMostRelevantFrame,
1810 pop_process_io_handler);
1811 }
1812
1813 output_stream_sp->Flush();
1814 error_stream_sp->Flush();
1815
1816 if (pop_process_io_handler)
1817 process_sp->PopProcessIOHandler();
1818 }
1819}
1820
1821void Debugger::HandleThreadEvent(const EventSP &event_sp) {
1822 // At present the only thread event we handle is the Frame Changed event, and
1823 // all we do for that is just reprint the thread status for that thread.
1824 using namespace lldb;
1825 const uint32_t event_type = event_sp->GetType();
1826 const bool stop_format = true;
1827 if (event_type == Thread::eBroadcastBitStackChanged ||
1828 event_type == Thread::eBroadcastBitThreadSelected) {
1829 ThreadSP thread_sp(
1830 Thread::ThreadEventData::GetThreadFromEvent(event_ptr: event_sp.get()));
1831 if (thread_sp) {
1832 thread_sp->GetStatus(strm&: *GetAsyncOutputStream(), start_frame: 0, num_frames: 1, num_frames_with_source: 1, stop_format);
1833 }
1834 }
1835}
1836
1837bool Debugger::IsForwardingEvents() { return (bool)m_forward_listener_sp; }
1838
1839void Debugger::EnableForwardEvents(const ListenerSP &listener_sp) {
1840 m_forward_listener_sp = listener_sp;
1841}
1842
1843void Debugger::CancelForwardEvents(const ListenerSP &listener_sp) {
1844 m_forward_listener_sp.reset();
1845}
1846
1847lldb::thread_result_t Debugger::DefaultEventHandler() {
1848 ListenerSP listener_sp(GetListener());
1849 ConstString broadcaster_class_target(Target::GetStaticBroadcasterClass());
1850 ConstString broadcaster_class_process(Process::GetStaticBroadcasterClass());
1851 ConstString broadcaster_class_thread(Thread::GetStaticBroadcasterClass());
1852 BroadcastEventSpec target_event_spec(broadcaster_class_target,
1853 Target::eBroadcastBitBreakpointChanged);
1854
1855 BroadcastEventSpec process_event_spec(
1856 broadcaster_class_process,
1857 Process::eBroadcastBitStateChanged | Process::eBroadcastBitSTDOUT |
1858 Process::eBroadcastBitSTDERR | Process::eBroadcastBitStructuredData);
1859
1860 BroadcastEventSpec thread_event_spec(broadcaster_class_thread,
1861 Thread::eBroadcastBitStackChanged |
1862 Thread::eBroadcastBitThreadSelected);
1863
1864 listener_sp->StartListeningForEventSpec(manager_sp: m_broadcaster_manager_sp,
1865 event_spec: target_event_spec);
1866 listener_sp->StartListeningForEventSpec(manager_sp: m_broadcaster_manager_sp,
1867 event_spec: process_event_spec);
1868 listener_sp->StartListeningForEventSpec(manager_sp: m_broadcaster_manager_sp,
1869 event_spec: thread_event_spec);
1870 listener_sp->StartListeningForEvents(
1871 broadcaster: m_command_interpreter_up.get(),
1872 event_mask: CommandInterpreter::eBroadcastBitQuitCommandReceived |
1873 CommandInterpreter::eBroadcastBitAsynchronousOutputData |
1874 CommandInterpreter::eBroadcastBitAsynchronousErrorData);
1875
1876 listener_sp->StartListeningForEvents(
1877 broadcaster: &m_broadcaster, event_mask: eBroadcastBitProgress | eBroadcastBitWarning |
1878 eBroadcastBitError | eBroadcastSymbolChange);
1879
1880 // Let the thread that spawned us know that we have started up and that we
1881 // are now listening to all required events so no events get missed
1882 m_sync_broadcaster.BroadcastEvent(event_type: eBroadcastBitEventThreadIsListening);
1883
1884 bool done = false;
1885 while (!done) {
1886 EventSP event_sp;
1887 if (listener_sp->GetEvent(event_sp, timeout: std::nullopt)) {
1888 if (event_sp) {
1889 Broadcaster *broadcaster = event_sp->GetBroadcaster();
1890 if (broadcaster) {
1891 uint32_t event_type = event_sp->GetType();
1892 ConstString broadcaster_class(broadcaster->GetBroadcasterClass());
1893 if (broadcaster_class == broadcaster_class_process) {
1894 HandleProcessEvent(event_sp);
1895 } else if (broadcaster_class == broadcaster_class_target) {
1896 if (Breakpoint::BreakpointEventData::GetEventDataFromEvent(
1897 event_sp: event_sp.get())) {
1898 HandleBreakpointEvent(event_sp);
1899 }
1900 } else if (broadcaster_class == broadcaster_class_thread) {
1901 HandleThreadEvent(event_sp);
1902 } else if (broadcaster == m_command_interpreter_up.get()) {
1903 if (event_type &
1904 CommandInterpreter::eBroadcastBitQuitCommandReceived) {
1905 done = true;
1906 } else if (event_type &
1907 CommandInterpreter::eBroadcastBitAsynchronousErrorData) {
1908 const char *data = static_cast<const char *>(
1909 EventDataBytes::GetBytesFromEvent(event_ptr: event_sp.get()));
1910 if (data && data[0]) {
1911 StreamSP error_sp(GetAsyncErrorStream());
1912 if (error_sp) {
1913 error_sp->PutCString(cstr: data);
1914 error_sp->Flush();
1915 }
1916 }
1917 } else if (event_type & CommandInterpreter::
1918 eBroadcastBitAsynchronousOutputData) {
1919 const char *data = static_cast<const char *>(
1920 EventDataBytes::GetBytesFromEvent(event_ptr: event_sp.get()));
1921 if (data && data[0]) {
1922 StreamSP output_sp(GetAsyncOutputStream());
1923 if (output_sp) {
1924 output_sp->PutCString(cstr: data);
1925 output_sp->Flush();
1926 }
1927 }
1928 }
1929 } else if (broadcaster == &m_broadcaster) {
1930 if (event_type & Debugger::eBroadcastBitProgress)
1931 HandleProgressEvent(event_sp);
1932 else if (event_type & Debugger::eBroadcastBitWarning)
1933 HandleDiagnosticEvent(event_sp);
1934 else if (event_type & Debugger::eBroadcastBitError)
1935 HandleDiagnosticEvent(event_sp);
1936 }
1937 }
1938
1939 if (m_forward_listener_sp)
1940 m_forward_listener_sp->AddEvent(event&: event_sp);
1941 }
1942 }
1943 }
1944 return {};
1945}
1946
1947bool Debugger::StartEventHandlerThread() {
1948 if (!m_event_handler_thread.IsJoinable()) {
1949 // We must synchronize with the DefaultEventHandler() thread to ensure it
1950 // is up and running and listening to events before we return from this
1951 // function. We do this by listening to events for the
1952 // eBroadcastBitEventThreadIsListening from the m_sync_broadcaster
1953 ConstString full_name("lldb.debugger.event-handler");
1954 ListenerSP listener_sp(Listener::MakeListener(name: full_name.AsCString()));
1955 listener_sp->StartListeningForEvents(broadcaster: &m_sync_broadcaster,
1956 event_mask: eBroadcastBitEventThreadIsListening);
1957
1958 llvm::StringRef thread_name =
1959 full_name.GetLength() < llvm::get_max_thread_name_length()
1960 ? full_name.GetStringRef()
1961 : "dbg.evt-handler";
1962
1963 // Use larger 8MB stack for this thread
1964 llvm::Expected<HostThread> event_handler_thread =
1965 ThreadLauncher::LaunchThread(
1966 name: thread_name, thread_function: [this] { return DefaultEventHandler(); },
1967 min_stack_byte_size: g_debugger_event_thread_stack_bytes);
1968
1969 if (event_handler_thread) {
1970 m_event_handler_thread = *event_handler_thread;
1971 } else {
1972 LLDB_LOG_ERROR(GetLog(LLDBLog::Host), event_handler_thread.takeError(),
1973 "failed to launch host thread: {0}");
1974 }
1975
1976 // Make sure DefaultEventHandler() is running and listening to events
1977 // before we return from this function. We are only listening for events of
1978 // type eBroadcastBitEventThreadIsListening so we don't need to check the
1979 // event, we just need to wait an infinite amount of time for it (nullptr
1980 // timeout as the first parameter)
1981 lldb::EventSP event_sp;
1982 listener_sp->GetEvent(event_sp, timeout: std::nullopt);
1983 }
1984 return m_event_handler_thread.IsJoinable();
1985}
1986
1987void Debugger::StopEventHandlerThread() {
1988 if (m_event_handler_thread.IsJoinable()) {
1989 GetCommandInterpreter().BroadcastEvent(
1990 event_type: CommandInterpreter::eBroadcastBitQuitCommandReceived);
1991 m_event_handler_thread.Join(result: nullptr);
1992 }
1993}
1994
1995lldb::thread_result_t Debugger::IOHandlerThread() {
1996 RunIOHandlers();
1997 StopEventHandlerThread();
1998 return {};
1999}
2000
2001void Debugger::HandleProgressEvent(const lldb::EventSP &event_sp) {
2002 auto *data = ProgressEventData::GetEventDataFromEvent(event_ptr: event_sp.get());
2003 if (!data)
2004 return;
2005
2006 // Do some bookkeeping for the current event, regardless of whether we're
2007 // going to show the progress.
2008 const uint64_t id = data->GetID();
2009 if (m_current_event_id) {
2010 Log *log = GetLog(mask: LLDBLog::Events);
2011 if (log && log->GetVerbose()) {
2012 StreamString log_stream;
2013 log_stream.AsRawOstream()
2014 << static_cast<void *>(this) << " Debugger(" << GetID()
2015 << ")::HandleProgressEvent( m_current_event_id = "
2016 << *m_current_event_id << ", data = { ";
2017 data->Dump(s: &log_stream);
2018 log_stream << " } )";
2019 log->PutString(str: log_stream.GetString());
2020 }
2021 if (id != *m_current_event_id)
2022 return;
2023 if (data->GetCompleted() == data->GetTotal())
2024 m_current_event_id.reset();
2025 } else {
2026 m_current_event_id = id;
2027 }
2028
2029 // Decide whether we actually are going to show the progress. This decision
2030 // can change between iterations so check it inside the loop.
2031 if (!GetShowProgress())
2032 return;
2033
2034 // Determine whether the current output file is an interactive terminal with
2035 // color support. We assume that if we support ANSI escape codes we support
2036 // vt100 escape codes.
2037 File &file = GetOutputFile();
2038 if (!file.GetIsInteractive() || !file.GetIsTerminalWithColors())
2039 return;
2040
2041 StreamSP output = GetAsyncOutputStream();
2042
2043 // Print over previous line, if any.
2044 output->Printf(format: "\r");
2045
2046 if (data->GetCompleted() == data->GetTotal()) {
2047 // Clear the current line.
2048 output->Printf(format: "\x1B[2K");
2049 output->Flush();
2050 return;
2051 }
2052
2053 // Trim the progress message if it exceeds the window's width and print it.
2054 std::string message = data->GetMessage();
2055 if (data->IsFinite())
2056 message = llvm::formatv(Fmt: "[{0}/{1}] {2}", Vals: data->GetCompleted(),
2057 Vals: data->GetTotal(), Vals&: message)
2058 .str();
2059
2060 // Trim the progress message if it exceeds the window's width and print it.
2061 const uint32_t term_width = GetTerminalWidth();
2062 const uint32_t ellipsis = 3;
2063 if (message.size() + ellipsis >= term_width)
2064 message = message.substr(pos: 0, n: term_width - ellipsis);
2065
2066 const bool use_color = GetUseColor();
2067 llvm::StringRef ansi_prefix = GetShowProgressAnsiPrefix();
2068 if (!ansi_prefix.empty())
2069 output->Printf(
2070 format: "%s", ansi::FormatAnsiTerminalCodes(format: ansi_prefix, do_color: use_color).c_str());
2071
2072 output->Printf(format: "%s...", message.c_str());
2073
2074 llvm::StringRef ansi_suffix = GetShowProgressAnsiSuffix();
2075 if (!ansi_suffix.empty())
2076 output->Printf(
2077 format: "%s", ansi::FormatAnsiTerminalCodes(format: ansi_suffix, do_color: use_color).c_str());
2078
2079 // Clear until the end of the line.
2080 output->Printf(format: "\x1B[K\r");
2081
2082 // Flush the output.
2083 output->Flush();
2084}
2085
2086void Debugger::HandleDiagnosticEvent(const lldb::EventSP &event_sp) {
2087 auto *data = DiagnosticEventData::GetEventDataFromEvent(event_ptr: event_sp.get());
2088 if (!data)
2089 return;
2090
2091 StreamSP stream = GetAsyncErrorStream();
2092 data->Dump(s: stream.get());
2093}
2094
2095bool Debugger::HasIOHandlerThread() const {
2096 return m_io_handler_thread.IsJoinable();
2097}
2098
2099HostThread Debugger::SetIOHandlerThread(HostThread &new_thread) {
2100 HostThread old_host = m_io_handler_thread;
2101 m_io_handler_thread = new_thread;
2102 return old_host;
2103}
2104
2105bool Debugger::StartIOHandlerThread() {
2106 if (!m_io_handler_thread.IsJoinable()) {
2107 llvm::Expected<HostThread> io_handler_thread = ThreadLauncher::LaunchThread(
2108 name: "lldb.debugger.io-handler", thread_function: [this] { return IOHandlerThread(); },
2109 min_stack_byte_size: 8 * 1024 * 1024); // Use larger 8MB stack for this thread
2110 if (io_handler_thread) {
2111 m_io_handler_thread = *io_handler_thread;
2112 } else {
2113 LLDB_LOG_ERROR(GetLog(LLDBLog::Host), io_handler_thread.takeError(),
2114 "failed to launch host thread: {0}");
2115 }
2116 }
2117 return m_io_handler_thread.IsJoinable();
2118}
2119
2120void Debugger::StopIOHandlerThread() {
2121 if (m_io_handler_thread.IsJoinable()) {
2122 GetInputFile().Close();
2123 m_io_handler_thread.Join(result: nullptr);
2124 }
2125}
2126
2127void Debugger::JoinIOHandlerThread() {
2128 if (HasIOHandlerThread()) {
2129 thread_result_t result;
2130 m_io_handler_thread.Join(result: &result);
2131 m_io_handler_thread = LLDB_INVALID_HOST_THREAD;
2132 }
2133}
2134
2135bool Debugger::IsIOHandlerThreadCurrentThread() const {
2136 if (!HasIOHandlerThread())
2137 return false;
2138 return m_io_handler_thread.EqualsThread(thread: Host::GetCurrentThread());
2139}
2140
2141Target &Debugger::GetSelectedOrDummyTarget(bool prefer_dummy) {
2142 if (!prefer_dummy) {
2143 if (TargetSP target = m_target_list.GetSelectedTarget())
2144 return *target;
2145 }
2146 return GetDummyTarget();
2147}
2148
2149Status Debugger::RunREPL(LanguageType language, const char *repl_options) {
2150 Status err;
2151 FileSpec repl_executable;
2152
2153 if (language == eLanguageTypeUnknown)
2154 language = GetREPLLanguage();
2155
2156 if (language == eLanguageTypeUnknown) {
2157 LanguageSet repl_languages = Language::GetLanguagesSupportingREPLs();
2158
2159 if (auto single_lang = repl_languages.GetSingularLanguage()) {
2160 language = *single_lang;
2161 } else if (repl_languages.Empty()) {
2162 err.SetErrorString(
2163 "LLDB isn't configured with REPL support for any languages.");
2164 return err;
2165 } else {
2166 err.SetErrorString(
2167 "Multiple possible REPL languages. Please specify a language.");
2168 return err;
2169 }
2170 }
2171
2172 Target *const target =
2173 nullptr; // passing in an empty target means the REPL must create one
2174
2175 REPLSP repl_sp(REPL::Create(Status&: err, language, debugger: this, target, repl_options));
2176
2177 if (!err.Success()) {
2178 return err;
2179 }
2180
2181 if (!repl_sp) {
2182 err.SetErrorStringWithFormat("couldn't find a REPL for %s",
2183 Language::GetNameForLanguageType(language));
2184 return err;
2185 }
2186
2187 repl_sp->SetCompilerOptions(repl_options);
2188 repl_sp->RunLoop();
2189
2190 return err;
2191}
2192
2193llvm::ThreadPool &Debugger::GetThreadPool() {
2194 assert(g_thread_pool &&
2195 "Debugger::GetThreadPool called before Debugger::Initialize");
2196 return *g_thread_pool;
2197}
2198

source code of lldb/source/Core/Debugger.cpp