LLDB mainline
Debugger.cpp
Go to the documentation of this file.
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
10
14#include "lldb/Core/Mangled.h"
18#include "lldb/Core/Progress.h"
21#include "lldb/Core/Telemetry.h"
24#include "lldb/Host/File.h"
26#include "lldb/Host/HostInfo.h"
28#include "lldb/Host/Terminal.h"
40#include "lldb/Symbol/Symbol.h"
43#include "lldb/Target/Process.h"
45#include "lldb/Target/Target.h"
47#include "lldb/Target/Thread.h"
50#include "lldb/Utility/Event.h"
53#include "lldb/Utility/Log.h"
54#include "lldb/Utility/State.h"
55#include "lldb/Utility/Stream.h"
59
60#if defined(_WIN32)
63#endif
64
65#include "llvm/ADT/STLExtras.h"
66#include "llvm/ADT/StringRef.h"
67#include "llvm/ADT/iterator.h"
68#include "llvm/Config/llvm-config.h"
69#include "llvm/Support/DynamicLibrary.h"
70#include "llvm/Support/FileSystem.h"
71#include "llvm/Support/Process.h"
72#include "llvm/Support/ThreadPool.h"
73#include "llvm/Support/Threading.h"
74#include "llvm/Support/raw_ostream.h"
75
76#include <chrono>
77#include <cstdio>
78#include <cstdlib>
79#include <cstring>
80#include <list>
81#include <memory>
82#include <mutex>
83#include <optional>
84#include <set>
85#include <string>
86#include <system_error>
87
88// Includes for pipe()
89#if defined(_WIN32)
90#include <fcntl.h>
91#include <io.h>
92#else
93#include <unistd.h>
94#endif
95
96namespace lldb_private {
97class Address;
98}
99
100using namespace lldb;
101using namespace lldb_private;
102
104static size_t g_debugger_event_thread_stack_bytes = 8 * 1024 * 1024;
105
106#pragma mark Static Functions
107
108static std::recursive_mutex *g_debugger_list_mutex_ptr =
109 nullptr; // NOTE: intentional leak to avoid issues with C++ destructor chain
111 nullptr; // NOTE: intentional leak to avoid issues with C++ destructor chain
112static llvm::DefaultThreadPool *g_thread_pool = nullptr;
113
115 {
117 "never",
118 "Never show disassembly when displaying a stop context.",
119 },
120 {
122 "no-debuginfo",
123 "Show disassembly when there is no debug information.",
124 },
125 {
127 "no-source",
128 "Show disassembly when there is no source information, or the source "
129 "file "
130 "is missing when displaying a stop context.",
131 },
132 {
134 "always",
135 "Always show disassembly when displaying a stop context.",
136 },
137};
138
140 {
142 "none",
143 "Disable scripting languages.",
144 },
145 {
147 "python",
148 "Select python as the default scripting language.",
149 },
150 {
152 "default",
153 "Select the lldb default as the default scripting language.",
154 },
155};
156
159 "Use no verbosity when running dwim-print."},
160 {eDWIMPrintVerbosityExpression, "expression",
161 "Use partial verbosity when running dwim-print - display a message when "
162 "`expression` evaluation is used."},
164 "Use full verbosity when running dwim-print."},
165};
166
168 {
170 "ansi-or-caret",
171 "Highlight the stop column with ANSI terminal codes when color/ANSI "
172 "mode is enabled; otherwise, fall back to using a text-only caret (^) "
173 "as if \"caret-only\" mode was selected.",
174 },
175 {
177 "ansi",
178 "Highlight the stop column with ANSI terminal codes when running LLDB "
179 "with color/ANSI enabled.",
180 },
181 {
183 "caret",
184 "Highlight the stop column with a caret character (^) underneath the "
185 "stop column. This method introduces a new line in source listings "
186 "that display thread stop locations.",
187 },
188 {
190 "none",
191 "Do not highlight the stop column.",
192 },
193};
194
195#define LLDB_PROPERTIES_debugger
196#include "CoreProperties.inc"
197
198enum {
199#define LLDB_PROPERTIES_debugger
200#include "CorePropertiesEnum.inc"
201};
202
204
207 llvm::StringRef property_path,
208 llvm::StringRef value) {
209 bool is_load_script =
210 (property_path == "target.load-script-from-symbol-file");
211 // These properties might change how we visualize data.
212 bool invalidate_data_vis = (property_path == "escape-non-printables");
213 invalidate_data_vis |=
214 (property_path == "target.max-zero-padding-in-float-format");
215 if (invalidate_data_vis) {
217 }
218
219 TargetSP target_sp;
221 if (is_load_script && exe_ctx && exe_ctx->GetTargetSP()) {
222 target_sp = exe_ctx->GetTargetSP();
223 load_script_old_value =
224 target_sp->TargetProperties::GetLoadScriptFromSymbolFile();
225 }
226 Status error(Properties::SetPropertyValue(exe_ctx, op, property_path, value));
227 if (error.Success()) {
228 // FIXME it would be nice to have "on-change" callbacks for properties
229 if (property_path == g_debugger_properties[ePropertyPrompt].name) {
230 llvm::StringRef new_prompt = GetPrompt();
232 new_prompt, GetUseColor());
233 if (str.length())
234 new_prompt = str;
236 auto bytes = std::make_unique<EventDataBytes>(new_prompt);
237 auto prompt_change_event_sp = std::make_shared<Event>(
239 GetCommandInterpreter().BroadcastEvent(prompt_change_event_sp);
240 } else if (property_path == g_debugger_properties[ePropertyUseColor].name) {
241 // use-color changed. set use-color, this also pings the prompt so it can
242 // reset the ansi terminal codes.
244 } else if (property_path ==
245 g_debugger_properties[ePropertyPromptAnsiPrefix].name ||
246 property_path ==
247 g_debugger_properties[ePropertyPromptAnsiSuffix].name) {
248 // Prompt color changed. set use-color, this also pings the prompt so it
249 // can reset the ansi terminal codes.
251 } else if (property_path ==
252 g_debugger_properties[ePropertyShowStatusline].name) {
253 // Statusline setting changed. If we have a statusline instance, update it
254 // now. Otherwise it will get created in the default event handler.
255 std::lock_guard<std::mutex> guard(m_statusline_mutex);
256 if (StatuslineSupported()) {
257 m_statusline.emplace(*this);
259 } else {
260 m_statusline.reset();
261 }
262 } else if (property_path ==
263 g_debugger_properties[ePropertyStatuslineFormat].name ||
264 property_path ==
265 g_debugger_properties[ePropertySeparator].name) {
266 // Statusline format changed. Redraw the statusline.
267 RedrawStatusline(std::nullopt);
268 } else if (property_path ==
269 g_debugger_properties[ePropertyUseSourceCache].name) {
270 // use-source-cache changed. Wipe out the cache contents if it was
271 // disabled.
272 if (!GetUseSourceCache()) {
273 m_source_file_cache.Clear();
274 }
275 } else if (is_load_script && target_sp &&
276 load_script_old_value == eLoadScriptFromSymFileWarn) {
277 if (target_sp->TargetProperties::GetLoadScriptFromSymbolFile() ==
279 std::list<Status> errors;
280 StreamString feedback_stream;
281 if (!target_sp->LoadScriptingResources(errors, feedback_stream)) {
283 for (auto &error : errors)
284 s->Printf("%s\n", error.AsCString());
285 if (feedback_stream.GetSize())
286 s->PutCString(feedback_stream.GetString());
287 }
288 }
289 }
290 }
291 return error;
292}
293
295 constexpr uint32_t idx = ePropertyAutoConfirm;
297 idx, g_debugger_properties[idx].default_uint_value != 0);
298}
299
301 constexpr uint32_t idx = ePropertyDisassemblyFormat;
303}
304
306 constexpr uint32_t idx = ePropertyFrameFormat;
308}
309
311 constexpr uint32_t idx = ePropertyFrameFormatUnique;
313}
314
316 constexpr uint32_t idx = ePropertyStopDisassemblyMaxSize;
318 idx, g_debugger_properties[idx].default_uint_value);
319}
320
322 constexpr uint32_t idx = ePropertyNotiftVoid;
324 idx, g_debugger_properties[idx].default_uint_value != 0);
325}
326
327llvm::StringRef Debugger::GetPrompt() const {
328 constexpr uint32_t idx = ePropertyPrompt;
330 idx, g_debugger_properties[idx].default_cstr_value);
331}
332
333llvm::StringRef Debugger::GetPromptAnsiPrefix() const {
334 const uint32_t idx = ePropertyPromptAnsiPrefix;
336 idx, g_debugger_properties[idx].default_cstr_value);
337}
338
339llvm::StringRef Debugger::GetPromptAnsiSuffix() const {
340 const uint32_t idx = ePropertyPromptAnsiSuffix;
342 idx, g_debugger_properties[idx].default_cstr_value);
343}
344
345void Debugger::SetPrompt(llvm::StringRef p) {
346 constexpr uint32_t idx = ePropertyPrompt;
347 SetPropertyAtIndex(idx, p);
348 llvm::StringRef new_prompt = GetPrompt();
349 std::string str =
351 if (str.length())
352 new_prompt = str;
354}
355
357 constexpr uint32_t idx = ePropertyThreadFormat;
359}
360
362 constexpr uint32_t idx = ePropertyThreadStopFormat;
364}
365
367 const uint32_t idx = ePropertyScriptLanguage;
369 idx, static_cast<lldb::ScriptLanguage>(
370 g_debugger_properties[idx].default_uint_value));
371}
372
374 const uint32_t idx = ePropertyScriptLanguage;
375 return SetPropertyAtIndex(idx, script_lang);
376}
377
379 const uint32_t idx = ePropertyREPLLanguage;
381}
382
384 const uint32_t idx = ePropertyREPLLanguage;
385 return SetPropertyAtIndex(idx, repl_lang);
386}
387
389 const uint32_t idx = ePropertyTerminalWidth;
391 idx, g_debugger_properties[idx].default_uint_value);
392}
393
394bool Debugger::SetTerminalWidth(uint64_t term_width) {
395 const uint32_t idx = ePropertyTerminalWidth;
396 const bool success = SetPropertyAtIndex(idx, term_width);
397
398 if (auto handler_sp = m_io_handler_stack.Top())
399 handler_sp->TerminalSizeChanged();
400
401 {
402 std::lock_guard<std::mutex> guard(m_statusline_mutex);
403 if (m_statusline)
404 m_statusline->TerminalSizeChanged();
405 }
406
407 return success;
408}
409
411 const uint32_t idx = ePropertyTerminalHeight;
413 idx, g_debugger_properties[idx].default_uint_value);
414}
415
416bool Debugger::SetTerminalHeight(uint64_t term_height) {
417 const uint32_t idx = ePropertyTerminalHeight;
418 const bool success = SetPropertyAtIndex(idx, term_height);
419
420 if (auto handler_sp = m_io_handler_stack.Top())
421 handler_sp->TerminalSizeChanged();
422
423 {
424 std::lock_guard<std::mutex> guard(m_statusline_mutex);
425 if (m_statusline)
426 m_statusline->TerminalSizeChanged();
427 }
428
429 return success;
430}
431
433 const uint32_t idx = ePropertyUseExternalEditor;
435 idx, g_debugger_properties[idx].default_uint_value != 0);
436}
437
439 const uint32_t idx = ePropertyUseExternalEditor;
440 return SetPropertyAtIndex(idx, b);
441}
442
443llvm::StringRef Debugger::GetExternalEditor() const {
444 const uint32_t idx = ePropertyExternalEditor;
446 idx, g_debugger_properties[idx].default_cstr_value);
447}
448
449bool Debugger::SetExternalEditor(llvm::StringRef editor) {
450 const uint32_t idx = ePropertyExternalEditor;
451 return SetPropertyAtIndex(idx, editor);
452}
453
455 const uint32_t idx = ePropertyUseColor;
457 idx, g_debugger_properties[idx].default_uint_value != 0);
458}
459
461 const uint32_t idx = ePropertyUseColor;
462 bool ret = SetPropertyAtIndex(idx, b);
463
466 return ret;
467}
468
470 const uint32_t idx = ePropertyShowProgress;
472 idx, g_debugger_properties[idx].default_uint_value != 0);
473}
474
475bool Debugger::SetShowProgress(bool show_progress) {
476 const uint32_t idx = ePropertyShowProgress;
477 return SetPropertyAtIndex(idx, show_progress);
478}
479
480llvm::StringRef Debugger::GetShowProgressAnsiPrefix() const {
481 const uint32_t idx = ePropertyShowProgressAnsiPrefix;
483 idx, g_debugger_properties[idx].default_cstr_value);
484}
485
486llvm::StringRef Debugger::GetShowProgressAnsiSuffix() const {
487 const uint32_t idx = ePropertyShowProgressAnsiSuffix;
489 idx, g_debugger_properties[idx].default_cstr_value);
490}
491
493 const uint32_t idx = ePropertyShowStatusline;
495 idx, g_debugger_properties[idx].default_uint_value != 0);
496}
497
499 constexpr uint32_t idx = ePropertyStatuslineFormat;
501}
502
504 constexpr uint32_t idx = ePropertyStatuslineFormat;
505 bool ret = SetPropertyAtIndex(idx, format);
506 RedrawStatusline(std::nullopt);
507 return ret;
508}
509
510llvm::StringRef Debugger::GetSeparator() const {
511 constexpr uint32_t idx = ePropertySeparator;
513 idx, g_debugger_properties[idx].default_cstr_value);
514}
515
516llvm::StringRef Debugger::GetDisabledAnsiPrefix() const {
517 const uint32_t idx = ePropertyShowDisabledAnsiPrefix;
519 idx, g_debugger_properties[idx].default_cstr_value);
520}
521
522llvm::StringRef Debugger::GetDisabledAnsiSuffix() const {
523 const uint32_t idx = ePropertyShowDisabledAnsiSuffix;
525 idx, g_debugger_properties[idx].default_cstr_value);
526}
527
528bool Debugger::SetSeparator(llvm::StringRef s) {
529 constexpr uint32_t idx = ePropertySeparator;
530 bool ret = SetPropertyAtIndex(idx, s);
531 RedrawStatusline(std::nullopt);
532 return ret;
533}
534
536 const uint32_t idx = ePropertyShowAutosuggestion;
538 idx, g_debugger_properties[idx].default_uint_value != 0);
539}
540
542 const uint32_t idx = ePropertyShowAutosuggestionAnsiPrefix;
544 idx, g_debugger_properties[idx].default_cstr_value);
545}
546
548 const uint32_t idx = ePropertyShowAutosuggestionAnsiSuffix;
550 idx, g_debugger_properties[idx].default_cstr_value);
551}
552
553llvm::StringRef Debugger::GetRegexMatchAnsiPrefix() const {
554 const uint32_t idx = ePropertyShowRegexMatchAnsiPrefix;
556 idx, g_debugger_properties[idx].default_cstr_value);
557}
558
559llvm::StringRef Debugger::GetRegexMatchAnsiSuffix() const {
560 const uint32_t idx = ePropertyShowRegexMatchAnsiSuffix;
562 idx, g_debugger_properties[idx].default_cstr_value);
563}
564
566 const uint32_t idx = ePropertyShowDontUsePoHint;
568 idx, g_debugger_properties[idx].default_uint_value != 0);
569}
570
572 const uint32_t idx = ePropertyUseSourceCache;
574 idx, g_debugger_properties[idx].default_uint_value != 0);
575}
576
578 const uint32_t idx = ePropertyUseSourceCache;
579 bool ret = SetPropertyAtIndex(idx, b);
580 if (!ret) {
581 m_source_file_cache.Clear();
582 }
583 return ret;
584}
586 const uint32_t idx = ePropertyHighlightSource;
588 idx, g_debugger_properties[idx].default_uint_value != 0);
589}
590
592 const uint32_t idx = ePropertyStopShowColumn;
594 idx, static_cast<lldb::StopShowColumn>(
595 g_debugger_properties[idx].default_uint_value));
596}
597
599 const uint32_t idx = ePropertyStopShowColumnAnsiPrefix;
601 idx, g_debugger_properties[idx].default_cstr_value);
602}
603
605 const uint32_t idx = ePropertyStopShowColumnAnsiSuffix;
607 idx, g_debugger_properties[idx].default_cstr_value);
608}
609
611 const uint32_t idx = ePropertyStopShowLineMarkerAnsiPrefix;
613 idx, g_debugger_properties[idx].default_cstr_value);
614}
615
617 const uint32_t idx = ePropertyStopShowLineMarkerAnsiSuffix;
619 idx, g_debugger_properties[idx].default_cstr_value);
620}
621
622uint64_t Debugger::GetStopSourceLineCount(bool before) const {
623 const uint32_t idx =
624 before ? ePropertyStopLineCountBefore : ePropertyStopLineCountAfter;
626 idx, g_debugger_properties[idx].default_uint_value);
627}
628
630 const uint32_t idx = ePropertyStopDisassemblyDisplay;
632 idx, static_cast<lldb::StopDisassemblyType>(
633 g_debugger_properties[idx].default_uint_value));
634}
635
637 const uint32_t idx = ePropertyStopDisassemblyCount;
639 idx, g_debugger_properties[idx].default_uint_value);
640}
641
643 const uint32_t idx = ePropertyAutoOneLineSummaries;
645 idx, g_debugger_properties[idx].default_uint_value != 0);
646}
647
649 const uint32_t idx = ePropertyEscapeNonPrintables;
651 idx, g_debugger_properties[idx].default_uint_value != 0);
652}
653
655 const uint32_t idx = ePropertyAutoIndent;
657 idx, g_debugger_properties[idx].default_uint_value != 0);
658}
659
661 const uint32_t idx = ePropertyAutoIndent;
662 return SetPropertyAtIndex(idx, b);
663}
664
666 const uint32_t idx = ePropertyPrintDecls;
668 idx, g_debugger_properties[idx].default_uint_value != 0);
669}
670
672 const uint32_t idx = ePropertyPrintDecls;
673 return SetPropertyAtIndex(idx, b);
674}
675
676uint64_t Debugger::GetTabSize() const {
677 const uint32_t idx = ePropertyTabSize;
679 idx, g_debugger_properties[idx].default_uint_value);
680}
681
682bool Debugger::SetTabSize(uint64_t tab_size) {
683 const uint32_t idx = ePropertyTabSize;
684 return SetPropertyAtIndex(idx, tab_size);
685}
686
688 const uint32_t idx = ePropertyDWIMPrintVerbosity;
690 idx, static_cast<lldb::DWIMPrintVerbosity>(
691 g_debugger_properties[idx].default_uint_value != 0));
692}
693
695 const uint32_t idx = ePropertyShowInlineDiagnostics;
697 idx, g_debugger_properties[idx].default_uint_value);
698}
699
701 const uint32_t idx = ePropertyShowInlineDiagnostics;
702 return SetPropertyAtIndex(idx, b);
703}
704
705#pragma mark Debugger
706
707// const DebuggerPropertiesSP &
708// Debugger::GetSettings() const
709//{
710// return m_properties_sp;
711//}
712//
713
715 assert(g_debugger_list_ptr == nullptr &&
716 "Debugger::Initialize called more than once!");
717 g_debugger_list_mutex_ptr = new std::recursive_mutex();
719 g_thread_pool = new llvm::DefaultThreadPool(llvm::optimal_concurrency());
720 g_load_plugin_callback = load_plugin_callback;
721}
722
724 assert(g_debugger_list_ptr &&
725 "Debugger::Terminate called without a matching Debugger::Initialize!");
726
728 std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
729 for (const auto &debugger : *g_debugger_list_ptr)
730 debugger->HandleDestroyCallback();
731 }
732
733 if (g_thread_pool) {
734 // The destructor will wait for all the threads to complete.
735 delete g_thread_pool;
736 }
737
739 // Clear our global list of debugger objects
740 {
741 std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
742 for (const auto &debugger : *g_debugger_list_ptr)
743 debugger->Clear();
744 g_debugger_list_ptr->clear();
745 }
746 }
747}
748
750
752
755 llvm::sys::DynamicLibrary dynlib =
756 g_load_plugin_callback(shared_from_this(), spec, error);
757 if (dynlib.isValid()) {
758 m_loaded_plugins.push_back(dynlib);
759 return true;
760 }
761 } else {
762 // The g_load_plugin_callback is registered in SBDebugger::Initialize() and
763 // if the public API layer isn't available (code is linking against all of
764 // the internal LLDB static libraries), then we can't load plugins
765 error = Status::FromErrorString("Public API layer is not available");
766 }
767 return false;
768}
769
771LoadPluginCallback(void *baton, llvm::sys::fs::file_type ft,
772 llvm::StringRef path) {
774
775 static constexpr llvm::StringLiteral g_dylibext(".dylib");
776 static constexpr llvm::StringLiteral g_solibext(".so");
777
778 if (!baton)
780
781 Debugger *debugger = (Debugger *)baton;
782
783 namespace fs = llvm::sys::fs;
784 // If we have a regular file, a symbolic link or unknown file type, try and
785 // process the file. We must handle unknown as sometimes the directory
786 // enumeration might be enumerating a file system that doesn't have correct
787 // file type information.
788 if (ft == fs::file_type::regular_file || ft == fs::file_type::symlink_file ||
789 ft == fs::file_type::type_unknown) {
790 FileSpec plugin_file_spec(path);
791 FileSystem::Instance().Resolve(plugin_file_spec);
792
793 if (plugin_file_spec.GetFileNameExtension() != g_dylibext &&
794 plugin_file_spec.GetFileNameExtension() != g_solibext) {
796 }
797
798 Status plugin_load_error;
799 debugger->LoadPlugin(plugin_file_spec, plugin_load_error);
800
802 } else if (ft == fs::file_type::directory_file ||
803 ft == fs::file_type::symlink_file ||
804 ft == fs::file_type::type_unknown) {
805 // Try and recurse into anything that a directory or symbolic link. We must
806 // also do this for unknown as sometimes the directory enumeration might be
807 // enumerating a file system that doesn't have correct file type
808 // information.
810 }
811
813}
814
816 const bool find_directories = true;
817 const bool find_files = true;
818 const bool find_other = true;
819 char dir_path[PATH_MAX];
820 if (FileSpec dir_spec = HostInfo::GetSystemPluginDir()) {
821 if (FileSystem::Instance().Exists(dir_spec) &&
822 dir_spec.GetPath(dir_path, sizeof(dir_path))) {
823 FileSystem::Instance().EnumerateDirectory(dir_path, find_directories,
824 find_files, find_other,
825 LoadPluginCallback, this);
826 }
827 }
828
829 if (FileSpec dir_spec = HostInfo::GetUserPluginDir()) {
830 if (FileSystem::Instance().Exists(dir_spec) &&
831 dir_spec.GetPath(dir_path, sizeof(dir_path))) {
832 FileSystem::Instance().EnumerateDirectory(dir_path, find_directories,
833 find_files, find_other,
834 LoadPluginCallback, this);
835 }
836 }
837
839}
840
842 void *baton) {
845 helper([](lldb_private::telemetry::DebuggerInfo *entry) {
847 });
848 DebuggerSP debugger_sp(new Debugger(log_callback, baton));
849 helper.SetDebugger(debugger_sp.get());
850
852 std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
853 g_debugger_list_ptr->push_back(debugger_sp);
854 }
855 debugger_sp->InstanceInitialize();
856 return debugger_sp;
857}
858
864
866 const lldb::user_id_t user_id = GetID();
867 // Invoke and remove all the callbacks in an FIFO order. Callbacks which are
868 // added during this loop will be appended, invoked and then removed last.
869 // Callbacks which are removed during this loop will not be invoked.
870 while (true) {
871 DestroyCallbackInfo callback_info;
872 {
873 std::lock_guard<std::mutex> guard(m_destroy_callback_mutex);
874 if (m_destroy_callbacks.empty())
875 break;
876 // Pop the first item in the list
877 callback_info = m_destroy_callbacks.front();
879 }
880 // Call the destroy callback with user id and baton
881 callback_info.callback(user_id, callback_info.baton);
882 }
883}
884
885void Debugger::Destroy(DebuggerSP &debugger_sp) {
886 if (!debugger_sp)
887 return;
888
889 debugger_sp->HandleDestroyCallback();
890 CommandInterpreter &cmd_interpreter = debugger_sp->GetCommandInterpreter();
891
892 if (cmd_interpreter.GetSaveSessionOnQuit()) {
893 CommandReturnObject result(debugger_sp->GetUseColor());
894 cmd_interpreter.SaveTranscript(result);
895 if (result.Succeeded())
896 (*debugger_sp->GetAsyncOutputStream())
897 << result.GetOutputString() << '\n';
898 else
899 (*debugger_sp->GetAsyncErrorStream()) << result.GetErrorString() << '\n';
900 }
901
902 debugger_sp->Clear();
903
905 std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
906 DebuggerList::iterator pos, end = g_debugger_list_ptr->end();
907 for (pos = g_debugger_list_ptr->begin(); pos != end; ++pos) {
908 if ((*pos).get() == debugger_sp.get()) {
909 g_debugger_list_ptr->erase(pos);
910 return;
911 }
912 }
913 }
914}
915
917Debugger::FindDebuggerWithInstanceName(llvm::StringRef instance_name) {
919 return DebuggerSP();
920
921 std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
922 for (const DebuggerSP &debugger_sp : *g_debugger_list_ptr) {
923 if (!debugger_sp)
924 continue;
925
926 if (llvm::StringRef(debugger_sp->GetInstanceName()) == instance_name)
927 return debugger_sp;
928 }
929 return DebuggerSP();
930}
931
933 TargetSP target_sp;
935 std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
936 DebuggerList::iterator pos, end = g_debugger_list_ptr->end();
937 for (pos = g_debugger_list_ptr->begin(); pos != end; ++pos) {
938 target_sp = (*pos)->GetTargetList().FindTargetWithProcessID(pid);
939 if (target_sp)
940 break;
941 }
942 }
943 return target_sp;
944}
945
947 TargetSP target_sp;
949 std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
950 DebuggerList::iterator pos, end = g_debugger_list_ptr->end();
951 for (pos = g_debugger_list_ptr->begin(); pos != end; ++pos) {
952 target_sp = (*pos)->GetTargetList().FindTargetWithProcess(process);
953 if (target_sp)
954 break;
955 }
956 }
957 return target_sp;
958}
959
961 static constexpr llvm::StringLiteral class_name("lldb.debugger");
962 return class_name;
963}
964
966 : UserID(g_unique_id++),
967 Properties(std::make_shared<OptionValueProperties>()),
968 m_input_file_sp(std::make_shared<NativeFile>(stdin, NativeFile::Unowned)),
969 m_output_stream_sp(std::make_shared<LockableStreamFile>(
970 stdout, NativeFile::Unowned, m_output_mutex)),
971 m_error_stream_sp(std::make_shared<LockableStreamFile>(
972 stderr, NativeFile::Unowned, m_output_mutex)),
973 m_broadcaster_manager_sp(BroadcasterManager::MakeBroadcasterManager()),
975 m_listener_sp(Listener::MakeListener("lldb.Debugger")),
978 std::make_unique<CommandInterpreter>(*this, false)),
980 m_instance_name(llvm::formatv("debugger_{0}", GetID()).str()),
982 m_sync_broadcaster(nullptr, "lldb.debugger.sync"),
986 // Initialize the debugger properties as early as possible as other parts of
987 // LLDB will start querying them during construction.
988 m_collection_sp->Initialize(g_debugger_properties);
989 m_collection_sp->AppendProperty(
990 "target", "Settings specify to debugging targets.", true,
992 m_collection_sp->AppendProperty(
993 "platform", "Platform settings.", true,
995 m_collection_sp->AppendProperty(
996 "symbols", "Symbol lookup and cache settings.", true,
998 m_collection_sp->AppendProperty(
999 LanguageProperties::GetSettingName(), "Language settings.", true,
1002 m_collection_sp->AppendProperty(
1003 "interpreter",
1004 "Settings specify to the debugger's command interpreter.", true,
1005 m_command_interpreter_up->GetValueProperties());
1006 }
1007 if (log_callback)
1009 std::make_shared<CallbackLogHandler>(log_callback, baton);
1010 m_command_interpreter_up->Initialize();
1011 // Always add our default platform to the platform list
1012 PlatformSP default_platform_sp(Platform::GetHostPlatform());
1013 assert(default_platform_sp);
1014 m_platform_list.Append(default_platform_sp, true);
1015
1016 // Create the dummy target.
1017 {
1019 if (!arch.IsValid())
1020 arch = HostInfo::GetArchitecture();
1021 assert(arch.IsValid() && "No valid default or host archspec");
1022 const bool is_dummy_target = true;
1023 m_dummy_target_sp.reset(
1024 new Target(*this, arch, default_platform_sp, is_dummy_target));
1025 }
1026 assert(m_dummy_target_sp.get() && "Couldn't construct dummy target?");
1027
1028 OptionValueUInt64 *term_width =
1029 m_collection_sp->GetPropertyAtIndexAsOptionValueUInt64(
1030 ePropertyTerminalWidth);
1031 term_width->SetMinimumValue(10);
1032
1033 OptionValueUInt64 *term_height =
1034 m_collection_sp->GetPropertyAtIndexAsOptionValueUInt64(
1035 ePropertyTerminalHeight);
1036 term_height->SetMinimumValue(10);
1037
1038 // Turn off use-color if this is a dumb terminal.
1039 const char *term = getenv("TERM");
1040 auto disable_color = [&]() {
1041 SetUseColor(false);
1042 SetSeparator("| ");
1043 };
1044
1045 if (term && !strcmp(term, "dumb"))
1046 disable_color();
1047 // Turn off use-color if we don't write to a terminal with color support.
1048 if (!GetOutputFileSP()->GetIsTerminalWithColors())
1049 disable_color();
1050
1051 if (Diagnostics::Enabled()) {
1053 [this](const FileSpec &dir) -> llvm::Error {
1054 for (auto &entry : m_stream_handlers) {
1055 llvm::StringRef log_path = entry.first();
1056 llvm::StringRef file_name = llvm::sys::path::filename(log_path);
1057 FileSpec destination = dir.CopyByAppendingPathComponent(file_name);
1058 std::error_code ec =
1059 llvm::sys::fs::copy_file(log_path, destination.GetPath());
1060 if (ec)
1061 return llvm::errorCodeToError(ec);
1062 }
1063 return llvm::Error::success();
1064 });
1065 }
1066
1067#if defined(_WIN32) && defined(ENABLE_VIRTUAL_TERMINAL_PROCESSING)
1068 // Enabling use of ANSI color codes because LLDB is using them to highlight
1069 // text.
1070 llvm::sys::Process::UseANSIEscapeCodes(true);
1071#endif
1072}
1073
1075
1077 // Make sure we call this function only once. With the C++ global destructor
1078 // chain having a list of debuggers and with code that can be running on
1079 // other threads, we need to ensure this doesn't happen multiple times.
1080 //
1081 // The following functions call Debugger::Clear():
1082 // Debugger::~Debugger();
1083 // static void Debugger::Destroy(lldb::DebuggerSP &debugger_sp);
1084 // static void Debugger::Terminate();
1085 llvm::call_once(m_clear_once, [this]() {
1088 assert(this == info->debugger);
1089 (void)this;
1090 info->is_exit_entry = true;
1091 },
1092 this);
1096 m_listener_sp->Clear();
1097 for (TargetSP target_sp : m_target_list.Targets()) {
1098 if (target_sp) {
1099 if (ProcessSP process_sp = target_sp->GetProcessSP())
1100 process_sp->Finalize(false /* not destructing */);
1101 target_sp->Destroy();
1102 }
1103 }
1104 m_broadcaster_manager_sp->Clear();
1105
1106 // Close the input file _before_ we close the input read communications
1107 // class as it does NOT own the input file, our m_input_file does.
1108 m_terminal_state.Clear();
1109 GetInputFile().Close();
1110
1111 m_command_interpreter_up->Clear();
1112
1115 });
1116}
1117
1119 return !m_command_interpreter_up->GetSynchronous();
1120}
1121
1122void Debugger::SetAsyncExecution(bool async_execution) {
1123 m_command_interpreter_up->SetSynchronous(!async_execution);
1124}
1125
1126static inline int OpenPipe(int fds[2], std::size_t size) {
1127#ifdef _WIN32
1128 return _pipe(fds, size, O_BINARY);
1129#else
1130 (void)size;
1131 return pipe(fds);
1132#endif
1133}
1134
1136 Status result;
1137 enum PIPES { READ, WRITE }; // Indexes for the read and write fds
1138 int fds[2] = {-1, -1};
1139
1140 if (data == nullptr) {
1141 result = Status::FromErrorString("String data is null");
1142 return result;
1143 }
1144
1145 size_t size = strlen(data);
1146 if (size == 0) {
1147 result = Status::FromErrorString("String data is empty");
1148 return result;
1149 }
1150
1151 if (OpenPipe(fds, size) != 0) {
1152 result = Status::FromErrorString(
1153 "can't create pipe file descriptors for LLDB commands");
1154 return result;
1155 }
1156
1157 int r = write(fds[WRITE], data, size);
1158 (void)r;
1159 // Close the write end of the pipe, so that the command interpreter will exit
1160 // when it consumes all the data.
1161 llvm::sys::Process::SafelyCloseFileDescriptor(fds[WRITE]);
1162
1163 // Open the read file descriptor as a FILE * that we can return as an input
1164 // handle.
1165 FILE *commands_file = fdopen(fds[READ], "rb");
1166 if (commands_file == nullptr) {
1168 "fdopen(%i, \"rb\") failed (errno = %i) "
1169 "when trying to open LLDB commands pipe",
1170 fds[READ], errno);
1171 llvm::sys::Process::SafelyCloseFileDescriptor(fds[READ]);
1172 return result;
1173 }
1174
1175 SetInputFile((FileSP)std::make_shared<NativeFile>(commands_file, true));
1176 return result;
1177}
1178
1180 assert(file_sp && file_sp->IsValid());
1181 m_input_file_sp = std::move(file_sp);
1182 // Save away the terminal state if that is relevant, so that we can restore
1183 // it in RestoreInputState.
1185}
1186
1188 assert(file_sp && file_sp->IsValid());
1190 std::make_shared<LockableStreamFile>(file_sp, m_output_mutex);
1191}
1192
1194 assert(file_sp && file_sp->IsValid());
1196 std::make_shared<LockableStreamFile>(file_sp, m_output_mutex);
1197}
1198
1200 {
1201 std::lock_guard<std::mutex> guard(m_statusline_mutex);
1202 if (m_statusline)
1203 m_statusline->Disable();
1204 }
1205 int fd = GetInputFile().GetDescriptor();
1206 if (fd != File::kInvalidDescriptor)
1207 m_terminal_state.Save(fd, true);
1208}
1209
1211 m_terminal_state.Restore();
1212 {
1213 std::lock_guard<std::mutex> guard(m_statusline_mutex);
1214 if (m_statusline)
1216 }
1217}
1218
1220 std::optional<ExecutionContextRef> exe_ctx_ref) {
1221 std::lock_guard<std::mutex> guard(m_statusline_mutex);
1222
1223 if (!m_statusline)
1224 return;
1225
1226 m_statusline->Redraw(exe_ctx_ref);
1227}
1228
1230 bool adopt_selected = true;
1231 ExecutionContextRef exe_ctx_ref(GetSelectedTarget().get(), adopt_selected);
1232 return ExecutionContext(exe_ctx_ref);
1233}
1234
1236 if (TargetSP selected_target_sp = GetSelectedTarget())
1237 return ExecutionContextRef(selected_target_sp.get(),
1238 /*adopt_selected=*/true);
1239 return ExecutionContextRef(m_dummy_target_sp.get(), /*adopt_selected=*/false);
1240}
1241
1243 std::lock_guard<std::recursive_mutex> guard(m_io_handler_stack.GetMutex());
1244 IOHandlerSP reader_sp(m_io_handler_stack.Top());
1245 if (reader_sp)
1246 reader_sp->Interrupt();
1247}
1248
1250 std::lock_guard<std::recursive_mutex> guard(m_io_handler_stack.GetMutex());
1251 IOHandlerSP reader_sp(m_io_handler_stack.Top());
1252 if (reader_sp)
1253 reader_sp->GotEOF();
1254}
1255
1257 // The bottom input reader should be the main debugger input reader. We do
1258 // not want to close that one here.
1259 std::lock_guard<std::recursive_mutex> guard(m_io_handler_stack.GetMutex());
1260 while (m_io_handler_stack.GetSize() > 1) {
1261 IOHandlerSP reader_sp(m_io_handler_stack.Top());
1262 if (reader_sp)
1263 PopIOHandler(reader_sp);
1264 }
1265}
1266
1268 IOHandlerSP reader_sp = m_io_handler_stack.Top();
1269 while (true) {
1270 if (!reader_sp)
1271 break;
1272
1273 reader_sp->Run();
1274 {
1275 std::lock_guard<std::recursive_mutex> guard(
1277
1278 // Remove all input readers that are done from the top of the stack
1279 while (true) {
1280 IOHandlerSP top_reader_sp = m_io_handler_stack.Top();
1281 if (top_reader_sp && top_reader_sp->GetIsDone())
1282 PopIOHandler(top_reader_sp);
1283 else
1284 break;
1285 }
1286 reader_sp = m_io_handler_stack.Top();
1287 }
1288 }
1290}
1291
1293 std::lock_guard<std::recursive_mutex> guard(m_io_handler_synchronous_mutex);
1294
1295 PushIOHandler(reader_sp);
1296 IOHandlerSP top_reader_sp = reader_sp;
1297
1298 while (top_reader_sp) {
1299 top_reader_sp->Run();
1300
1301 // Don't unwind past the starting point.
1302 if (top_reader_sp.get() == reader_sp.get()) {
1303 if (PopIOHandler(reader_sp))
1304 break;
1305 }
1306
1307 // If we pushed new IO handlers, pop them if they're done or restart the
1308 // loop to run them if they're not.
1309 while (true) {
1310 top_reader_sp = m_io_handler_stack.Top();
1311 if (top_reader_sp && top_reader_sp->GetIsDone()) {
1312 PopIOHandler(top_reader_sp);
1313 // Don't unwind past the starting point.
1314 if (top_reader_sp.get() == reader_sp.get())
1315 return;
1316 } else {
1317 break;
1318 }
1319 }
1320 }
1321}
1322
1324 return m_io_handler_stack.IsTop(reader_sp);
1325}
1326
1328 IOHandler::Type second_top_type) {
1329 return m_io_handler_stack.CheckTopIOHandlerTypes(top_type, second_top_type);
1330}
1331
1332void Debugger::PrintAsync(const char *s, size_t len, bool is_stdout) {
1333 bool printed = m_io_handler_stack.PrintAsync(s, len, is_stdout);
1334 if (!printed) {
1335 LockableStreamFileSP stream_sp =
1337 LockedStreamFile locked_stream = stream_sp->Lock();
1338 locked_stream.Write(s, len);
1339 }
1340}
1341
1343 return m_io_handler_stack.GetTopIOHandlerControlSequence(ch);
1344}
1345
1347 return m_io_handler_stack.GetTopIOHandlerCommandPrefix();
1348}
1349
1351 return m_io_handler_stack.GetTopIOHandlerHelpPrologue();
1352}
1353
1355 return PopIOHandler(reader_sp);
1356}
1357
1359 bool cancel_top_handler) {
1360 PushIOHandler(reader_sp, cancel_top_handler);
1361}
1362
1365 LockableStreamFileSP &err) {
1366 // Before an IOHandler runs, it must have in/out/err streams. This function
1367 // is called when one ore more of the streams are nullptr. We use the top
1368 // input reader's in/out/err streams, or fall back to the debugger file
1369 // handles, or we fall back onto stdin/stdout/stderr as a last resort.
1370
1371 std::lock_guard<std::recursive_mutex> guard(m_io_handler_stack.GetMutex());
1372 IOHandlerSP top_reader_sp(m_io_handler_stack.Top());
1373 // If no STDIN has been set, then set it appropriately
1374 if (!in || !in->IsValid()) {
1375 if (top_reader_sp)
1376 in = top_reader_sp->GetInputFileSP();
1377 else
1378 in = GetInputFileSP();
1379 // If there is nothing, use stdin
1380 if (!in)
1381 in = std::make_shared<NativeFile>(stdin, NativeFile::Unowned);
1382 }
1383 // If no STDOUT has been set, then set it appropriately
1384 if (!out || !out->GetUnlockedFile().IsValid()) {
1385 if (top_reader_sp)
1386 out = top_reader_sp->GetOutputStreamFileSP();
1387 else
1388 out = GetOutputStreamSP();
1389 // If there is nothing, use stdout
1390 if (!out)
1391 out = std::make_shared<LockableStreamFile>(stdout, NativeFile::Unowned,
1393 }
1394 // If no STDERR has been set, then set it appropriately
1395 if (!err || !err->GetUnlockedFile().IsValid()) {
1396 if (top_reader_sp)
1397 err = top_reader_sp->GetErrorStreamFileSP();
1398 else
1399 err = GetErrorStreamSP();
1400 // If there is nothing, use stderr
1401 if (!err)
1402 err = std::make_shared<LockableStreamFile>(stderr, NativeFile::Unowned,
1404 }
1405}
1406
1408 bool cancel_top_handler) {
1409 if (!reader_sp)
1410 return;
1411
1412 std::lock_guard<std::recursive_mutex> guard(m_io_handler_stack.GetMutex());
1413
1414 // Get the current top input reader...
1415 IOHandlerSP top_reader_sp(m_io_handler_stack.Top());
1416
1417 // Don't push the same IO handler twice...
1418 if (reader_sp == top_reader_sp)
1419 return;
1420
1421 // Push our new input reader
1422 m_io_handler_stack.Push(reader_sp);
1423 reader_sp->Activate();
1424
1425 // Interrupt the top input reader to it will exit its Run() function and let
1426 // this new input reader take over
1427 if (top_reader_sp) {
1428 top_reader_sp->Deactivate();
1429 if (cancel_top_handler)
1430 top_reader_sp->Cancel();
1431 }
1432}
1433
1434bool Debugger::PopIOHandler(const IOHandlerSP &pop_reader_sp) {
1435 if (!pop_reader_sp)
1436 return false;
1437
1438 std::lock_guard<std::recursive_mutex> guard(m_io_handler_stack.GetMutex());
1439
1440 // The reader on the stop of the stack is done, so let the next read on the
1441 // stack refresh its prompt and if there is one...
1442 if (m_io_handler_stack.IsEmpty())
1443 return false;
1444
1445 IOHandlerSP reader_sp(m_io_handler_stack.Top());
1446
1447 if (pop_reader_sp != reader_sp)
1448 return false;
1449
1450 reader_sp->Deactivate();
1451 reader_sp->Cancel();
1452 m_io_handler_stack.Pop();
1453
1454 reader_sp = m_io_handler_stack.Top();
1455 if (reader_sp)
1456 reader_sp->Activate();
1457
1458 return true;
1459}
1460
1462 std::lock_guard<std::recursive_mutex> guard(m_io_handler_stack.GetMutex());
1463 IOHandlerSP reader_sp(m_io_handler_stack.Top());
1464 if (reader_sp)
1465 reader_sp->Refresh();
1466}
1467
1469 return std::make_unique<StreamAsynchronousIO>(*this,
1471}
1472
1474 return std::make_unique<StreamAsynchronousIO>(*this,
1476}
1477
1479 std::lock_guard<std::mutex> guard(m_interrupt_mutex);
1481}
1482
1484 std::lock_guard<std::mutex> guard(m_interrupt_mutex);
1485 if (m_interrupt_requested > 0)
1487}
1488
1490 // This is the one we should call internally. This will return true either
1491 // if there's a debugger interrupt and we aren't on the IOHandler thread,
1492 // or if we are on the IOHandler thread and there's a CommandInterpreter
1493 // interrupt.
1495 std::lock_guard<std::mutex> guard(m_interrupt_mutex);
1496 return m_interrupt_requested != 0;
1497 }
1499}
1500
1502 std::string function_name, const llvm::formatv_object_base &payload)
1503 : m_function_name(std::move(function_name)),
1504 m_interrupt_time(std::chrono::system_clock::now()),
1505 m_thread_id(llvm::get_threadid()) {
1506 llvm::raw_string_ostream desc(m_description);
1507 desc << payload << "\n";
1508}
1509
1511 // For now, just log the description:
1512 Log *log = GetLog(LLDBLog::Host);
1513 LLDB_LOG(log, "Interruption: {0}", report.m_description);
1514}
1515
1517 DebuggerList result;
1519 std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
1520 for (auto debugger_sp : *g_debugger_list_ptr) {
1521 if (debugger_sp->InterruptRequested())
1522 result.push_back(debugger_sp);
1523 }
1524 }
1525 return result;
1526}
1527
1530 std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
1531 return g_debugger_list_ptr->size();
1532 }
1533 return 0;
1534}
1535
1537 DebuggerSP debugger_sp;
1538
1540 std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
1541 if (index < g_debugger_list_ptr->size())
1542 debugger_sp = g_debugger_list_ptr->at(index);
1543 }
1544
1545 return debugger_sp;
1546}
1547
1549 DebuggerSP debugger_sp;
1550
1552 std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
1553 DebuggerList::iterator pos, end = g_debugger_list_ptr->end();
1554 for (pos = g_debugger_list_ptr->begin(); pos != end; ++pos) {
1555 if ((*pos)->GetID() == id) {
1556 debugger_sp = *pos;
1557 break;
1558 }
1559 }
1560 }
1561 return debugger_sp;
1562}
1563
1565 const SymbolContext *sc,
1566 const SymbolContext *prev_sc,
1567 const ExecutionContext *exe_ctx,
1568 const Address *addr, Stream &s) {
1569 FormatEntity::Entry format_entry;
1570
1571 if (format == nullptr) {
1572 if (exe_ctx != nullptr && exe_ctx->HasTargetScope()) {
1573 format_entry =
1575 format = &format_entry;
1576 }
1577 if (format == nullptr) {
1578 FormatEntity::Parse("${addr}: ", format_entry);
1579 format = &format_entry;
1580 }
1581 }
1582 bool function_changed = false;
1583 bool initial_function = false;
1584 if (prev_sc && (prev_sc->function || prev_sc->symbol)) {
1585 if (sc && (sc->function || sc->symbol)) {
1586 if (prev_sc->symbol && sc->symbol) {
1587 if (!sc->symbol->Compare(prev_sc->symbol->GetName(),
1588 prev_sc->symbol->GetType())) {
1589 function_changed = true;
1590 }
1591 } else if (prev_sc->function && sc->function) {
1592 if (prev_sc->function->GetMangled() != sc->function->GetMangled()) {
1593 function_changed = true;
1594 }
1595 }
1596 }
1597 }
1598 // The first context on a list of instructions will have a prev_sc that has
1599 // no Function or Symbol -- if SymbolContext had an IsValid() method, it
1600 // would return false. But we do get a prev_sc pointer.
1601 if ((sc && (sc->function || sc->symbol)) && prev_sc &&
1602 (prev_sc->function == nullptr && prev_sc->symbol == nullptr)) {
1603 initial_function = true;
1604 }
1605 return FormatEntity::Format(*format, s, sc, exe_ctx, addr, nullptr,
1606 function_changed, initial_function);
1607}
1608
1609void Debugger::AssertCallback(llvm::StringRef message,
1610 llvm::StringRef backtrace,
1611 llvm::StringRef prompt) {
1612 Debugger::ReportError(llvm::formatv("{0}\n{1}{2}\n{3}", message, backtrace,
1613 GetVersion(), prompt)
1614 .str());
1615}
1616
1618 void *baton) {
1619 // For simplicity's sake, I am not going to deal with how to close down any
1620 // open logging streams, I just redirect everything from here on out to the
1621 // callback.
1623 std::make_shared<CallbackLogHandler>(log_callback, baton);
1624}
1625
1627 lldb_private::DebuggerDestroyCallback destroy_callback, void *baton) {
1628 std::lock_guard<std::mutex> guard(m_destroy_callback_mutex);
1629 m_destroy_callbacks.clear();
1631 m_destroy_callbacks.emplace_back(token, destroy_callback, baton);
1632}
1633
1635 lldb_private::DebuggerDestroyCallback destroy_callback, void *baton) {
1636 std::lock_guard<std::mutex> guard(m_destroy_callback_mutex);
1638 m_destroy_callbacks.emplace_back(token, destroy_callback, baton);
1639 return token;
1640}
1641
1643 std::lock_guard<std::mutex> guard(m_destroy_callback_mutex);
1644 for (auto it = m_destroy_callbacks.begin(); it != m_destroy_callbacks.end();
1645 ++it) {
1646 if (it->token == token) {
1647 m_destroy_callbacks.erase(it);
1648 return true;
1649 }
1650 }
1651 return false;
1652}
1653
1654static void PrivateReportProgress(Debugger &debugger, uint64_t progress_id,
1655 std::string title, std::string details,
1656 uint64_t completed, uint64_t total,
1657 bool is_debugger_specific,
1658 uint32_t progress_broadcast_bit) {
1659 // Only deliver progress events if we have any progress listeners.
1660 if (!debugger.GetBroadcaster().EventTypeHasListeners(progress_broadcast_bit))
1661 return;
1662
1663 EventSP event_sp(new Event(
1664 progress_broadcast_bit,
1665 new ProgressEventData(progress_id, std::move(title), std::move(details),
1666 completed, total, is_debugger_specific)));
1667 debugger.GetBroadcaster().BroadcastEvent(event_sp);
1668}
1669
1670void Debugger::ReportProgress(uint64_t progress_id, std::string title,
1671 std::string details, uint64_t completed,
1672 uint64_t total,
1673 std::optional<lldb::user_id_t> debugger_id,
1674 uint32_t progress_broadcast_bit) {
1675 // Check if this progress is for a specific debugger.
1676 if (debugger_id) {
1677 // It is debugger specific, grab it and deliver the event if the debugger
1678 // still exists.
1679 DebuggerSP debugger_sp = FindDebuggerWithID(*debugger_id);
1680 if (debugger_sp)
1681 PrivateReportProgress(*debugger_sp, progress_id, std::move(title),
1682 std::move(details), completed, total,
1683 /*is_debugger_specific*/ true,
1684 progress_broadcast_bit);
1685 return;
1686 }
1687 // The progress event is not debugger specific, iterate over all debuggers
1688 // and deliver a progress event to each one.
1690 std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
1691 DebuggerList::iterator pos, end = g_debugger_list_ptr->end();
1692 for (pos = g_debugger_list_ptr->begin(); pos != end; ++pos)
1693 PrivateReportProgress(*(*pos), progress_id, title, details, completed,
1694 total, /*is_debugger_specific*/ false,
1695 progress_broadcast_bit);
1696 }
1697}
1698
1699static void PrivateReportDiagnostic(Debugger &debugger, Severity severity,
1700 std::string message,
1701 bool debugger_specific) {
1702 uint32_t event_type = 0;
1703 switch (severity) {
1704 case eSeverityInfo:
1705 assert(false && "eSeverityInfo should not be broadcast");
1706 return;
1707 case eSeverityWarning:
1708 event_type = lldb::eBroadcastBitWarning;
1709 break;
1710 case eSeverityError:
1711 event_type = lldb::eBroadcastBitError;
1712 break;
1713 }
1714
1715 Broadcaster &broadcaster = debugger.GetBroadcaster();
1716 if (!broadcaster.EventTypeHasListeners(event_type)) {
1717 // Diagnostics are too important to drop. If nobody is listening, print the
1718 // diagnostic directly to the debugger's error stream.
1719 DiagnosticEventData event_data(severity, std::move(message),
1720 debugger_specific);
1721 event_data.Dump(debugger.GetAsyncErrorStream().get());
1722 return;
1723 }
1724 EventSP event_sp = std::make_shared<Event>(
1725 event_type,
1726 new DiagnosticEventData(severity, std::move(message), debugger_specific));
1727 broadcaster.BroadcastEvent(event_sp);
1728}
1729
1730void Debugger::ReportDiagnosticImpl(Severity severity, std::string message,
1731 std::optional<lldb::user_id_t> debugger_id,
1732 std::once_flag *once) {
1733 auto ReportDiagnosticLambda = [&]() {
1734 // Always log diagnostics to the system log.
1735 Host::SystemLog(severity, message);
1736
1737 // The diagnostic subsystem is optional but we still want to broadcast
1738 // events when it's disabled.
1740 Diagnostics::Instance().Report(message);
1741
1742 // We don't broadcast info events.
1743 if (severity == lldb::eSeverityInfo)
1744 return;
1745
1746 // Check if this diagnostic is for a specific debugger.
1747 if (debugger_id) {
1748 // It is debugger specific, grab it and deliver the event if the debugger
1749 // still exists.
1750 DebuggerSP debugger_sp = FindDebuggerWithID(*debugger_id);
1751 if (debugger_sp)
1752 PrivateReportDiagnostic(*debugger_sp, severity, std::move(message),
1753 true);
1754 return;
1755 }
1756 // The diagnostic event is not debugger specific, iterate over all debuggers
1757 // and deliver a diagnostic event to each one.
1759 std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
1760 for (const auto &debugger : *g_debugger_list_ptr)
1761 PrivateReportDiagnostic(*debugger, severity, message, false);
1762 }
1763 };
1764
1765 if (once)
1766 std::call_once(*once, ReportDiagnosticLambda);
1767 else
1768 ReportDiagnosticLambda();
1769}
1770
1771void Debugger::ReportWarning(std::string message,
1772 std::optional<lldb::user_id_t> debugger_id,
1773 std::once_flag *once) {
1774 ReportDiagnosticImpl(eSeverityWarning, std::move(message), debugger_id, once);
1775}
1776
1777void Debugger::ReportError(std::string message,
1778 std::optional<lldb::user_id_t> debugger_id,
1779 std::once_flag *once) {
1780 ReportDiagnosticImpl(eSeverityError, std::move(message), debugger_id, once);
1781}
1782
1783void Debugger::ReportInfo(std::string message,
1784 std::optional<lldb::user_id_t> debugger_id,
1785 std::once_flag *once) {
1786 ReportDiagnosticImpl(eSeverityInfo, std::move(message), debugger_id, once);
1787}
1788
1791 std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
1792 for (DebuggerSP debugger_sp : *g_debugger_list_ptr) {
1793 EventSP event_sp = std::make_shared<Event>(
1795 new SymbolChangeEventData(debugger_sp, module_spec));
1796 debugger_sp->GetBroadcaster().BroadcastEvent(event_sp);
1797 }
1798 }
1799}
1800
1801static std::shared_ptr<LogHandler>
1802CreateLogHandler(LogHandlerKind log_handler_kind, int fd, bool should_close,
1803 size_t buffer_size) {
1804 switch (log_handler_kind) {
1805 case eLogHandlerStream:
1806 return std::make_shared<StreamLogHandler>(fd, should_close, buffer_size);
1808 return std::make_shared<RotatingLogHandler>(buffer_size);
1809 case eLogHandlerSystem:
1810 return std::make_shared<SystemLogHandler>();
1812 return {};
1813 }
1814 return {};
1815}
1816
1817bool Debugger::EnableLog(llvm::StringRef channel,
1818 llvm::ArrayRef<const char *> categories,
1819 llvm::StringRef log_file, uint32_t log_options,
1820 size_t buffer_size, LogHandlerKind log_handler_kind,
1821 llvm::raw_ostream &error_stream) {
1822
1823 std::shared_ptr<LogHandler> log_handler_sp;
1825 log_handler_sp = m_callback_handler_sp;
1826 // For now when using the callback mode you always get thread & timestamp.
1827 log_options |=
1829 } else if (log_file.empty()) {
1830 log_handler_sp =
1831 CreateLogHandler(log_handler_kind, GetOutputFileSP()->GetDescriptor(),
1832 /*should_close=*/false, buffer_size);
1833 } else {
1834 auto pos = m_stream_handlers.find(log_file);
1835 if (pos != m_stream_handlers.end())
1836 log_handler_sp = pos->second.lock();
1837 if (!log_handler_sp) {
1838 File::OpenOptions flags =
1840 if (log_options & LLDB_LOG_OPTION_APPEND)
1841 flags |= File::eOpenOptionAppend;
1842 else
1844 llvm::Expected<FileUP> file = FileSystem::Instance().Open(
1845 FileSpec(log_file), flags, lldb::eFilePermissionsFileDefault, false);
1846 if (!file) {
1847 error_stream << "Unable to open log file '" << log_file
1848 << "': " << llvm::toString(file.takeError()) << "\n";
1849 return false;
1850 }
1851
1852 log_handler_sp =
1853 CreateLogHandler(log_handler_kind, (*file)->GetDescriptor(),
1854 /*should_close=*/true, buffer_size);
1855 m_stream_handlers[log_file] = log_handler_sp;
1856 }
1857 }
1858 assert(log_handler_sp);
1859
1860 if (log_options == 0)
1862
1863 return Log::EnableLogChannel(log_handler_sp, log_options, channel, categories,
1864 error_stream);
1865}
1866
1869 std::optional<lldb::ScriptLanguage> language) {
1870 std::lock_guard<std::recursive_mutex> locker(m_script_interpreter_mutex);
1871 lldb::ScriptLanguage script_language =
1872 language ? *language : GetScriptLanguage();
1873
1874 if (!m_script_interpreters[script_language]) {
1875 if (!can_create)
1876 return nullptr;
1877 m_script_interpreters[script_language] =
1878 PluginManager::GetScriptInterpreterForLanguage(script_language, *this);
1879 }
1880
1881 return m_script_interpreters[script_language].get();
1882}
1883
1886 m_source_manager_up = std::make_unique<SourceManager>(shared_from_this());
1887 return *m_source_manager_up;
1888}
1889
1890// This function handles events that were broadcast by the process.
1892 using namespace lldb;
1893 const uint32_t event_type =
1895 event_sp);
1896
1897 // if (event_type & eBreakpointEventTypeAdded
1898 // || event_type & eBreakpointEventTypeRemoved
1899 // || event_type & eBreakpointEventTypeEnabled
1900 // || event_type & eBreakpointEventTypeDisabled
1901 // || event_type & eBreakpointEventTypeCommandChanged
1902 // || event_type & eBreakpointEventTypeConditionChanged
1903 // || event_type & eBreakpointEventTypeIgnoreChanged
1904 // || event_type & eBreakpointEventTypeLocationsResolved)
1905 // {
1906 // // Don't do anything about these events, since the breakpoint
1907 // commands already echo these actions.
1908 // }
1909 //
1910 if (event_type & eBreakpointEventTypeLocationsAdded) {
1911 uint32_t num_new_locations =
1913 event_sp);
1914 if (num_new_locations > 0) {
1915 BreakpointSP breakpoint =
1917 if (StreamUP output_up = GetAsyncOutputStream()) {
1918 output_up->Printf("%d location%s added to breakpoint %d\n",
1919 num_new_locations, num_new_locations == 1 ? "" : "s",
1920 breakpoint->GetID());
1921 output_up->Flush();
1922 }
1923 }
1924 }
1925 // else if (event_type & eBreakpointEventTypeLocationsRemoved)
1926 // {
1927 // // These locations just get disabled, not sure it is worth spamming
1928 // folks about this on the command line.
1929 // }
1930 // else if (event_type & eBreakpointEventTypeLocationsResolved)
1931 // {
1932 // // This might be an interesting thing to note, but I'm going to
1933 // leave it quiet for now, it just looked noisy.
1934 // }
1935}
1936
1937void Debugger::FlushProcessOutput(Process &process, bool flush_stdout,
1938 bool flush_stderr) {
1939 const auto &flush = [&](Stream &stream,
1940 size_t (Process::*get)(char *, size_t, Status &)) {
1941 Status error;
1942 size_t len;
1943 char buffer[1024];
1944 while ((len = (process.*get)(buffer, sizeof(buffer), error)) > 0)
1945 stream.Write(buffer, len);
1946 stream.Flush();
1947 };
1948
1949 std::lock_guard<std::mutex> guard(m_output_flush_mutex);
1950 if (flush_stdout)
1952 if (flush_stderr)
1954}
1955
1956// This function handles events that were broadcast by the process.
1958 const uint32_t event_type = event_sp->GetType();
1959 ProcessSP process_sp =
1963
1964 StreamUP output_stream_up = GetAsyncOutputStream();
1965 StreamUP error_stream_up = GetAsyncErrorStream();
1966 const bool gui_enabled = IsForwardingEvents();
1967
1968 if (!gui_enabled) {
1969 bool pop_process_io_handler = false;
1970 assert(process_sp);
1971
1972 bool state_is_stopped = false;
1973 const bool got_state_changed =
1974 (event_type & Process::eBroadcastBitStateChanged) != 0;
1975 const bool got_stdout = (event_type & Process::eBroadcastBitSTDOUT) != 0;
1976 const bool got_stderr = (event_type & Process::eBroadcastBitSTDERR) != 0;
1977 const bool got_structured_data =
1978 (event_type & Process::eBroadcastBitStructuredData) != 0;
1979
1980 if (got_state_changed) {
1981 StateType event_state =
1983 state_is_stopped = StateIsStoppedState(event_state, false);
1984 }
1985
1986 // Display running state changes first before any STDIO
1987 if (got_state_changed && !state_is_stopped) {
1988 // This is a public stop which we are going to announce to the user, so
1989 // we should force the most relevant frame selection here.
1990 Process::HandleProcessStateChangedEvent(event_sp, output_stream_up.get(),
1992 pop_process_io_handler);
1993 }
1994
1995 // Now display STDOUT and STDERR
1996 FlushProcessOutput(*process_sp, got_stdout || got_state_changed,
1997 got_stderr || got_state_changed);
1998
1999 // Give structured data events an opportunity to display.
2000 if (got_structured_data) {
2001 StructuredDataPluginSP plugin_sp =
2003 if (plugin_sp) {
2004 auto structured_data_sp =
2006 StreamString content_stream;
2007 Status error =
2008 plugin_sp->GetDescription(structured_data_sp, content_stream);
2009 if (error.Success()) {
2010 if (!content_stream.GetString().empty()) {
2011 // Add newline.
2012 content_stream.PutChar('\n');
2013 content_stream.Flush();
2014
2015 // Print it.
2016 output_stream_up->PutCString(content_stream.GetString());
2017 }
2018 } else {
2019 error_stream_up->Format("Failed to print structured "
2020 "data with plugin {0}: {1}",
2021 plugin_sp->GetPluginName(), error);
2022 }
2023 }
2024 }
2025
2026 // Now display any stopped state changes after any STDIO
2027 if (got_state_changed && state_is_stopped) {
2028 Process::HandleProcessStateChangedEvent(event_sp, output_stream_up.get(),
2030 pop_process_io_handler);
2031 }
2032
2033 output_stream_up->Flush();
2034 error_stream_up->Flush();
2035
2036 if (pop_process_io_handler)
2037 process_sp->PopProcessIOHandler();
2038 }
2039 return process_sp;
2040}
2041
2043 // At present the only thread event we handle is the Frame Changed event, and
2044 // all we do for that is just reprint the thread status for that thread.
2045 const uint32_t event_type = event_sp->GetType();
2046 const bool stop_format = true;
2047 ThreadSP thread_sp;
2048 if (event_type == Thread::eBroadcastBitStackChanged ||
2050 thread_sp = Thread::ThreadEventData::GetThreadFromEvent(event_sp.get());
2051 if (thread_sp) {
2052 thread_sp->GetStatus(*GetAsyncOutputStream(), 0, 1, 1, stop_format,
2053 /*show_hidden*/ true);
2054 }
2055 }
2056 return thread_sp;
2057}
2058
2060
2062 m_forward_listener_sp = listener_sp;
2063}
2064
2066 m_forward_listener_sp.reset();
2067}
2068
2070// We have trouble with the contol codes on Windows, see
2071// https://github.com/llvm/llvm-project/issues/134846.
2072#ifndef _WIN32
2073 if (GetShowStatusline()) {
2075 File &file = stream_sp->GetUnlockedFile();
2076 return file.GetIsInteractive() && file.GetIsRealTerminal() &&
2078 }
2079 }
2080#endif
2081 return false;
2082}
2083
2084static bool RequiresFollowChildWorkaround(const Process &process) {
2085 // FIXME: https://github.com/llvm/llvm-project/issues/160216
2086 return process.GetFollowForkMode() == eFollowChild;
2087}
2088
2090 ListenerSP listener_sp(GetListener());
2091 ConstString broadcaster_class_target(Target::GetStaticBroadcasterClass());
2092 ConstString broadcaster_class_process(Process::GetStaticBroadcasterClass());
2093 ConstString broadcaster_class_thread(Thread::GetStaticBroadcasterClass());
2094 BroadcastEventSpec target_event_spec(broadcaster_class_target,
2096
2097 BroadcastEventSpec process_event_spec(
2098 broadcaster_class_process,
2101
2102 BroadcastEventSpec thread_event_spec(broadcaster_class_thread,
2105
2106 listener_sp->StartListeningForEventSpec(m_broadcaster_manager_sp,
2107 target_event_spec);
2108 listener_sp->StartListeningForEventSpec(m_broadcaster_manager_sp,
2109 process_event_spec);
2110 listener_sp->StartListeningForEventSpec(m_broadcaster_manager_sp,
2111 thread_event_spec);
2112 listener_sp->StartListeningForEvents(
2117
2118 listener_sp->StartListeningForEvents(
2123
2124 // Let the thread that spawned us know that we have started up and that we
2125 // are now listening to all required events so no events get missed
2127
2128 if (StatuslineSupported()) {
2129 std::lock_guard<std::mutex> guard(m_statusline_mutex);
2130 if (!m_statusline) {
2131 m_statusline.emplace(*this);
2133 }
2134 }
2135
2136 bool done = false;
2137 while (!done) {
2138 EventSP event_sp;
2139 if (listener_sp->GetEvent(event_sp, std::nullopt)) {
2140 std::optional<ExecutionContextRef> exe_ctx_ref = std::nullopt;
2141 if (event_sp) {
2142 Broadcaster *broadcaster = event_sp->GetBroadcaster();
2143 if (broadcaster) {
2144 uint32_t event_type = event_sp->GetType();
2145 ConstString broadcaster_class(broadcaster->GetBroadcasterClass());
2146 if (broadcaster_class == broadcaster_class_process) {
2147 if (ProcessSP process_sp = HandleProcessEvent(event_sp))
2148 if (!RequiresFollowChildWorkaround(*process_sp))
2149 exe_ctx_ref = ExecutionContextRef(process_sp.get(),
2150 /*adopt_selected=*/true);
2151 } else if (broadcaster_class == broadcaster_class_target) {
2153 event_sp.get())) {
2154 HandleBreakpointEvent(event_sp);
2155 }
2156 } else if (broadcaster_class == broadcaster_class_thread) {
2157 if (ThreadSP thread_sp = HandleThreadEvent(event_sp))
2158 if (!RequiresFollowChildWorkaround(*thread_sp->GetProcess()))
2159 exe_ctx_ref = ExecutionContextRef(thread_sp.get(),
2160 /*adopt_selected=*/true);
2161 } else if (broadcaster == m_command_interpreter_up.get()) {
2162 if (event_type &
2164 done = true;
2165 } else if (event_type &
2167 const char *data = static_cast<const char *>(
2168 EventDataBytes::GetBytesFromEvent(event_sp.get()));
2169 if (data && data[0]) {
2170 StreamUP error_up = GetAsyncErrorStream();
2171 error_up->PutCString(data);
2172 error_up->Flush();
2173 }
2174 } else if (event_type & CommandInterpreter::
2175 eBroadcastBitAsynchronousOutputData) {
2176 const char *data = static_cast<const char *>(
2177 EventDataBytes::GetBytesFromEvent(event_sp.get()));
2178 if (data && data[0]) {
2179 StreamUP output_up = GetAsyncOutputStream();
2180 output_up->PutCString(data);
2181 output_up->Flush();
2182 }
2183 }
2184 } else if (broadcaster == &m_broadcaster) {
2185 if (event_type & lldb::eBroadcastBitProgress ||
2187 HandleProgressEvent(event_sp);
2188 else if (event_type & lldb::eBroadcastBitWarning)
2189 HandleDiagnosticEvent(event_sp);
2190 else if (event_type & lldb::eBroadcastBitError)
2191 HandleDiagnosticEvent(event_sp);
2192 }
2193 }
2194
2196 m_forward_listener_sp->AddEvent(event_sp);
2197 }
2198 RedrawStatusline(exe_ctx_ref);
2199 }
2200 }
2201
2202 {
2203 std::lock_guard<std::mutex> guard(m_statusline_mutex);
2204 if (m_statusline)
2205 m_statusline.reset();
2206 }
2207
2208 return {};
2209}
2210
2212 if (!m_event_handler_thread.IsJoinable()) {
2213 // We must synchronize with the DefaultEventHandler() thread to ensure it
2214 // is up and running and listening to events before we return from this
2215 // function. We do this by listening to events for the
2216 // eBroadcastBitEventThreadIsListening from the m_sync_broadcaster
2217 ConstString full_name("lldb.debugger.event-handler");
2218 ListenerSP listener_sp(Listener::MakeListener(full_name.AsCString()));
2219 listener_sp->StartListeningForEvents(&m_sync_broadcaster,
2221
2222 llvm::StringRef thread_name =
2223 full_name.GetLength() < llvm::get_max_thread_name_length()
2224 ? full_name.GetStringRef()
2225 : "dbg.evt-handler";
2226
2227 // Use larger 8MB stack for this thread
2228 llvm::Expected<HostThread> event_handler_thread =
2230 thread_name, [this] { return DefaultEventHandler(); },
2232
2233 if (event_handler_thread) {
2234 m_event_handler_thread = *event_handler_thread;
2235 } else {
2236 LLDB_LOG_ERROR(GetLog(LLDBLog::Host), event_handler_thread.takeError(),
2237 "failed to launch host thread: {0}");
2238 }
2239
2240 // Make sure DefaultEventHandler() is running and listening to events
2241 // before we return from this function. We are only listening for events of
2242 // type eBroadcastBitEventThreadIsListening so we don't need to check the
2243 // event, we just need to wait an infinite amount of time for it (nullptr
2244 // timeout as the first parameter)
2245 lldb::EventSP event_sp;
2246 listener_sp->GetEvent(event_sp, std::nullopt);
2247 }
2248 return m_event_handler_thread.IsJoinable();
2249}
2250
2258
2264
2266 auto *data = ProgressEventData::GetEventDataFromEvent(event_sp.get());
2267 if (!data)
2268 return;
2269
2270 // Make a local copy of the incoming progress report that we'll store.
2271 ProgressReport progress_report{data->GetID(), data->GetCompleted(),
2272 data->GetTotal(), data->GetMessage()};
2273
2274 // Do some bookkeeping regardless of whether we're going to display
2275 // progress reports.
2276 {
2277 std::lock_guard<std::mutex> guard(m_progress_reports_mutex);
2278 auto it = llvm::find_if(m_progress_reports, [&](const auto &report) {
2279 return report.id == progress_report.id;
2280 });
2281 if (it != m_progress_reports.end()) {
2282 const bool complete = data->GetCompleted() == data->GetTotal();
2283 if (complete)
2284 m_progress_reports.erase(it);
2285 else
2286 *it = progress_report;
2287 } else {
2288 m_progress_reports.push_back(progress_report);
2289 }
2290 }
2291}
2292
2293std::optional<Debugger::ProgressReport>
2295 std::lock_guard<std::mutex> guard(m_progress_reports_mutex);
2296 if (m_progress_reports.empty())
2297 return std::nullopt;
2298 return m_progress_reports.back();
2299}
2300
2302 auto *data = DiagnosticEventData::GetEventDataFromEvent(event_sp.get());
2303 if (!data)
2304 return;
2305
2306 data->Dump(GetAsyncErrorStream().get());
2307}
2308
2310 return m_io_handler_thread.IsJoinable();
2311}
2312
2315 m_io_handler_thread = new_thread;
2316 return old_host;
2317}
2318
2320 if (!m_io_handler_thread.IsJoinable()) {
2321 llvm::Expected<HostThread> io_handler_thread = ThreadLauncher::LaunchThread(
2322 "lldb.debugger.io-handler", [this] { return IOHandlerThread(); },
2323 8 * 1024 * 1024); // Use larger 8MB stack for this thread
2324 if (io_handler_thread) {
2325 m_io_handler_thread = *io_handler_thread;
2326 } else {
2327 LLDB_LOG_ERROR(GetLog(LLDBLog::Host), io_handler_thread.takeError(),
2328 "failed to launch host thread: {0}");
2329 }
2330 }
2331 return m_io_handler_thread.IsJoinable();
2332}
2333
2335 if (m_io_handler_thread.IsJoinable()) {
2336 GetInputFile().Close();
2337 m_io_handler_thread.Join(nullptr);
2338 }
2339}
2340
2348
2350 if (!HasIOHandlerThread())
2351 return false;
2352 return m_io_handler_thread.EqualsThread(Host::GetCurrentThread());
2353}
2354
2356 if (!prefer_dummy) {
2357 if (TargetSP target = m_target_list.GetSelectedTarget())
2358 return *target;
2359 }
2360 return GetDummyTarget();
2361}
2362
2363Status Debugger::RunREPL(LanguageType language, const char *repl_options) {
2364 Status err;
2365 FileSpec repl_executable;
2366
2367 if (language == eLanguageTypeUnknown)
2368 language = GetREPLLanguage();
2369
2370 if (language == eLanguageTypeUnknown) {
2372
2373 if (auto single_lang = repl_languages.GetSingularLanguage()) {
2374 language = *single_lang;
2375 } else if (repl_languages.Empty()) {
2377 "LLDB isn't configured with REPL support for any languages.");
2378 return err;
2379 } else {
2381 "Multiple possible REPL languages. Please specify a language.");
2382 return err;
2383 }
2384 }
2385
2386 Target *const target =
2387 nullptr; // passing in an empty target means the REPL must create one
2388
2389 REPLSP repl_sp(REPL::Create(err, language, this, target, repl_options));
2390
2391 if (!err.Success()) {
2392 return err;
2393 }
2394
2395 if (!repl_sp) {
2397 "couldn't find a REPL for %s",
2399 return err;
2400 }
2401
2402 repl_sp->SetCompilerOptions(repl_options);
2403 repl_sp->RunLoop();
2404
2405 return err;
2406}
2407
2408llvm::ThreadPoolInterface &Debugger::GetThreadPool() {
2409 assert(g_thread_pool &&
2410 "Debugger::GetThreadPool called before Debugger::Initialize");
2411 return *g_thread_pool;
2412}
static llvm::raw_ostream & error(Stream &strm)
static bool RequiresFollowChildWorkaround(const Process &process)
static std::recursive_mutex * g_debugger_list_mutex_ptr
Definition Debugger.cpp:108
static llvm::DefaultThreadPool * g_thread_pool
Definition Debugger.cpp:112
static constexpr OptionEnumValueElement g_show_disassembly_enum_values[]
Definition Debugger.cpp:114
static lldb::user_id_t g_unique_id
Definition Debugger.cpp:103
static constexpr OptionEnumValueElement g_language_enumerators[]
Definition Debugger.cpp:139
static void PrivateReportDiagnostic(Debugger &debugger, Severity severity, std::string message, bool debugger_specific)
static constexpr OptionEnumValueElement g_dwim_print_verbosities[]
Definition Debugger.cpp:157
static constexpr OptionEnumValueElement s_stop_show_column_values[]
Definition Debugger.cpp:167
static void PrivateReportProgress(Debugger &debugger, uint64_t progress_id, std::string title, std::string details, uint64_t completed, uint64_t total, bool is_debugger_specific, uint32_t progress_broadcast_bit)
static Debugger::DebuggerList * g_debugger_list_ptr
Definition Debugger.cpp:110
static int OpenPipe(int fds[2], std::size_t size)
static size_t g_debugger_event_thread_stack_bytes
Definition Debugger.cpp:104
static FileSystem::EnumerateDirectoryResult LoadPluginCallback(void *baton, llvm::sys::fs::file_type ft, llvm::StringRef path)
Definition Debugger.cpp:771
static std::shared_ptr< LogHandler > CreateLogHandler(LogHandlerKind log_handler_kind, int fd, bool should_close, size_t buffer_size)
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
Definition Log.h:369
#define LLDB_LOG_OPTION_APPEND
Definition Log.h:42
#define LLDB_LOG_ERROR(log, error,...)
Definition Log.h:392
#define LLDB_LOG_OPTION_PREPEND_TIMESTAMP
Definition Log.h:38
#define LLDB_LOG_OPTION_PREPEND_THREAD_NAME
Definition Log.h:40
PIPES
Definition PipePosix.cpp:32
@ WRITE
Definition PipePosix.cpp:32
@ READ
Definition PipePosix.cpp:32
A section + offset based address class.
Definition Address.h:62
An architecture specification class.
Definition ArchSpec.h:31
bool IsValid() const
Tests if this ArchSpec is valid.
Definition ArchSpec.h:366
static lldb::BreakpointEventType GetBreakpointEventTypeFromEvent(const lldb::EventSP &event_sp)
static lldb::BreakpointSP GetBreakpointFromEvent(const lldb::EventSP &event_sp)
static const BreakpointEventData * GetEventDataFromEvent(const Event *event_sp)
static size_t GetNumBreakpointLocationsFromEvent(const lldb::EventSP &event_sp)
lldb::BroadcastEventSpec
Definition Broadcaster.h:40
An event broadcasting class.
bool EventTypeHasListeners(uint32_t event_type)
virtual llvm::StringRef GetBroadcasterClass() const
This needs to be filled in if you are going to register the broadcaster with the broadcaster manager ...
void BroadcastEvent(lldb::EventSP &event_sp)
Broadcast an event which has no associated data.
void UpdatePrompt(llvm::StringRef prompt)
bool SaveTranscript(CommandReturnObject &result, std::optional< std::string > output_file=std::nullopt)
Save the current debugger session transcript to a file on disk.
std::string GetErrorString(bool with_diagnostics=true) const
Return the errors as a string.
llvm::StringRef GetOutputString() const
A uniqued constant string class.
Definition ConstString.h:40
const char * AsCString(const char *value_if_empty=nullptr) const
Get the string value as a C string.
size_t GetLength() const
Get the length in bytes of string value.
llvm::StringRef GetStringRef() const
Get the string value as a llvm::StringRef.
const std::chrono::time_point< std::chrono::system_clock > m_interrupt_time
Definition Debugger.h:493
InterruptionReport(std::string function_name, std::string description)
Definition Debugger.h:475
A class to manage flag bits.
Definition Debugger.h:80
static void AssertCallback(llvm::StringRef message, llvm::StringRef backtrace, llvm::StringRef prompt)
llvm::StringRef GetAutosuggestionAnsiPrefix() const
Definition Debugger.cpp:541
bool SetUseExternalEditor(bool use_external_editor_p)
Definition Debugger.cpp:438
PlatformList m_platform_list
Definition Debugger.h:740
HostThread m_event_handler_thread
Definition Debugger.h:770
static lldb::TargetSP FindTargetWithProcessID(lldb::pid_t pid)
Definition Debugger.cpp:932
FormatEntity::Entry GetDisassemblyFormat() const
Definition Debugger.cpp:300
uint64_t GetDisassemblyLineCount() const
Definition Debugger.cpp:636
lldb::TargetSP GetSelectedTarget()
Definition Debugger.h:180
llvm::StringRef GetDisabledAnsiSuffix() const
Definition Debugger.cpp:522
uint64_t GetTerminalHeight() const
Definition Debugger.cpp:410
lldb::LockableStreamFileSP m_output_stream_sp
Definition Debugger.h:727
bool SetExternalEditor(llvm::StringRef editor)
Definition Debugger.cpp:449
void RequestInterrupt()
Interruption in LLDB:
void ReportInterruption(const InterruptionReport &report)
ExecutionContext GetSelectedExecutionContext()
Get the execution context representing the selected entities in the selected target.
const std::string m_instance_name
Definition Debugger.h:766
static void Terminate()
Definition Debugger.cpp:723
lldb::ThreadSP HandleThreadEvent(const lldb::EventSP &event_sp)
void HandleProgressEvent(const lldb::EventSP &event_sp)
SourceManager & GetSourceManager()
bool SetShowProgress(bool show_progress)
Definition Debugger.cpp:475
bool StartEventHandlerThread()
Manually start the global event handler thread.
bool SetUseSourceCache(bool use_source_cache)
Definition Debugger.cpp:577
void StopEventHandlerThread()
Manually stop the debugger's default event handler.
static void ReportInfo(std::string message, std::optional< lldb::user_id_t > debugger_id=std::nullopt, std::once_flag *once=nullptr)
Report info events.
void SetAsyncExecution(bool async)
HostThread SetIOHandlerThread(HostThread &new_thread)
void CancelForwardEvents(const lldb::ListenerSP &listener_sp)
bool GetPrintDecls() const
Definition Debugger.cpp:665
lldb::FileSP GetInputFileSP()
Definition Debugger.h:136
bool GetHighlightSource() const
Definition Debugger.cpp:585
llvm::StringMap< std::weak_ptr< LogHandler > > m_stream_handlers
Definition Debugger.h:764
CommandInterpreter & GetCommandInterpreter()
Definition Debugger.h:163
FormatEntity::Entry GetStatuslineFormat() const
Definition Debugger.cpp:498
LoadedPluginsList m_loaded_plugins
Definition Debugger.h:769
bool GetShowInlineDiagnostics() const
Definition Debugger.cpp:694
bool SetTabSize(uint64_t tab_size)
Definition Debugger.cpp:682
void HandleDiagnosticEvent(const lldb::EventSP &event_sp)
static lldb::DebuggerSP GetDebuggerAtIndex(size_t index)
llvm::StringRef GetAutosuggestionAnsiSuffix() const
Definition Debugger.cpp:547
lldb::ListenerSP m_listener_sp
Definition Debugger.h:741
void PushIOHandler(const lldb::IOHandlerSP &reader_sp, bool cancel_top_handler=true)
std::mutex m_destroy_callback_mutex
Definition Debugger.h:785
lldb::callback_token_t AddDestroyCallback(lldb_private::DebuggerDestroyCallback destroy_callback, void *baton)
Add a callback for when the debugger is destroyed.
lldb::thread_result_t IOHandlerThread()
FormatEntity::Entry GetFrameFormatUnique() const
Definition Debugger.cpp:310
std::optional< ProgressReport > GetCurrentProgressReport() const
static lldb::TargetSP FindTargetWithProcess(Process *process)
Definition Debugger.cpp:946
llvm::StringRef GetDisabledAnsiPrefix() const
Definition Debugger.cpp:516
bool GetUseExternalEditor() const
Definition Debugger.cpp:432
TerminalState m_terminal_state
Definition Debugger.h:737
lldb::StreamUP GetAsyncErrorStream()
bool GetEscapeNonPrintables() const
Definition Debugger.cpp:648
lldb::TargetSP m_dummy_target_sp
Definition Debugger.h:776
llvm::SmallVector< DestroyCallbackInfo, 2 > m_destroy_callbacks
Definition Debugger.h:797
std::unique_ptr< CommandInterpreter > m_command_interpreter_up
Definition Debugger.h:751
static void ReportWarning(std::string message, std::optional< lldb::user_id_t > debugger_id=std::nullopt, std::once_flag *once=nullptr)
Report warning events.
static bool FormatDisassemblerAddress(const FormatEntity::Entry *format, const SymbolContext *sc, const SymbolContext *prev_sc, const ExecutionContext *exe_ctx, const Address *addr, Stream &s)
static void SettingsInitialize()
Definition Debugger.cpp:749
LockableStreamFile::Mutex m_output_mutex
Definition Debugger.h:729
static llvm::ThreadPoolInterface & GetThreadPool()
Shared thread pool. Use only with ThreadPoolTaskGroup.
llvm::StringRef GetShowProgressAnsiSuffix() const
Definition Debugger.cpp:486
bool IsTopIOHandler(const lldb::IOHandlerSP &reader_sp)
bool HasIOHandlerThread() const
llvm::SmallVector< ProgressReport, 4 > m_progress_reports
Bookkeeping for command line progress events.
Definition Debugger.h:781
bool IsIOHandlerThreadCurrentThread() const
void DispatchClientTelemetry(const lldb_private::StructuredDataImpl &entry)
Definition Debugger.cpp:859
std::mutex m_progress_reports_mutex
Definition Debugger.h:782
lldb::ProcessSP HandleProcessEvent(const lldb::EventSP &event_sp)
lldb::ListenerSP m_forward_listener_sp
Definition Debugger.h:774
std::array< lldb::ScriptInterpreterSP, lldb::eScriptLanguageUnknown > m_script_interpreters
Definition Debugger.h:755
std::shared_ptr< CallbackLogHandler > m_callback_handler_sp
Definition Debugger.h:765
void SetDestroyCallback(lldb_private::DebuggerDestroyCallback destroy_callback, void *baton)
DEPRECATED: We used to only support one Destroy callback.
lldb::FileSP GetOutputFileSP()
Definition Debugger.h:139
Broadcaster m_broadcaster
Public Debugger event broadcaster.
Definition Debugger.h:773
static void Initialize(LoadPluginCallbackType load_plugin_callback)
Definition Debugger.cpp:714
static lldb::DebuggerSP FindDebuggerWithInstanceName(llvm::StringRef instance_name)
Definition Debugger.cpp:917
uint64_t GetTerminalWidth() const
Definition Debugger.cpp:388
std::mutex m_interrupt_mutex
Definition Debugger.h:800
std::recursive_mutex m_io_handler_synchronous_mutex
Definition Debugger.h:758
bool RemoveIOHandler(const lldb::IOHandlerSP &reader_sp)
Remove the given IO handler if it's currently active.
Diagnostics::CallbackID m_diagnostics_callback_id
Definition Debugger.h:777
bool GetAutoOneLineSummaries() const
Definition Debugger.cpp:642
const char * GetIOHandlerCommandPrefix()
std::optional< Statusline > m_statusline
Definition Debugger.h:762
bool GetUseColor() const
Definition Debugger.cpp:454
lldb::BroadcasterManagerSP m_broadcaster_manager_sp
Definition Debugger.h:731
Status RunREPL(lldb::LanguageType language, const char *repl_options)
bool PopIOHandler(const lldb::IOHandlerSP &reader_sp)
bool RemoveDestroyCallback(lldb::callback_token_t token)
Remove the specified callback. Return true if successful.
static LoadPluginCallbackType g_load_plugin_callback
Definition Debugger.h:767
bool GetShowStatusline() const
Definition Debugger.cpp:492
std::recursive_mutex m_script_interpreter_mutex
Definition Debugger.h:753
void RunIOHandlerAsync(const lldb::IOHandlerSP &reader_sp, bool cancel_top_handler=true)
Run the given IO handler and return immediately.
void SetInputFile(lldb::FileSP file)
lldb::LockableStreamFileSP GetOutputStreamSP()
Except for Debugger and IOHandler, GetOutputStreamSP and GetErrorStreamSP should not be used directly...
Definition Debugger.h:681
void SetPrompt(llvm::StringRef p)
Definition Debugger.cpp:345
llvm::StringRef GetSeparator() const
Definition Debugger.cpp:510
bool EnableLog(llvm::StringRef channel, llvm::ArrayRef< const char * > categories, llvm::StringRef log_file, uint32_t log_options, size_t buffer_size, LogHandlerKind log_handler_kind, llvm::raw_ostream &error_stream)
uint64_t GetStopDisassemblyMaxSize() const
Definition Debugger.cpp:315
bool SetTerminalHeight(uint64_t term_height)
Definition Debugger.cpp:416
Broadcaster m_sync_broadcaster
Private debugger synchronization.
Definition Debugger.h:772
bool GetUseSourceCache() const
Definition Debugger.cpp:571
HostThread m_io_handler_thread
Definition Debugger.h:771
llvm::StringRef GetRegexMatchAnsiSuffix() const
Definition Debugger.cpp:559
static llvm::StringRef GetStaticBroadcasterClass()
Definition Debugger.cpp:960
lldb::FileSP m_input_file_sp
Definition Debugger.h:726
bool SetREPLLanguage(lldb::LanguageType repl_lang)
Definition Debugger.cpp:383
bool GetAutoIndent() const
Definition Debugger.cpp:654
llvm::StringRef GetStopShowColumnAnsiSuffix() const
Definition Debugger.cpp:604
Status SetPropertyValue(const ExecutionContext *exe_ctx, VarSetOperationType op, llvm::StringRef property_path, llvm::StringRef value) override
Definition Debugger.cpp:205
llvm::StringRef GetPromptAnsiSuffix() const
Definition Debugger.cpp:339
FormatEntity::Entry GetThreadStopFormat() const
Definition Debugger.cpp:361
void SetErrorFile(lldb::FileSP file)
bool GetAutoConfirm() const
Definition Debugger.cpp:294
TargetList m_target_list
Definition Debugger.h:738
lldb::ScriptLanguage GetScriptLanguage() const
Definition Debugger.cpp:366
lldb::callback_token_t m_destroy_callback_next_token
Definition Debugger.h:786
std::unique_ptr< SourceManager > m_source_manager_up
Definition Debugger.h:742
static lldb::DebuggerSP CreateInstance(lldb::LogOutputCallback log_callback=nullptr, void *baton=nullptr)
Definition Debugger.cpp:841
lldb::StopShowColumn GetStopShowColumn() const
Definition Debugger.cpp:591
static void ReportSymbolChange(const ModuleSpec &module_spec)
static void ReportError(std::string message, std::optional< lldb::user_id_t > debugger_id=std::nullopt, std::once_flag *once=nullptr)
Report error events.
bool SetPrintDecls(bool b)
Definition Debugger.cpp:671
bool SetScriptLanguage(lldb::ScriptLanguage script_lang)
Definition Debugger.cpp:373
lldb::LockableStreamFileSP m_error_stream_sp
Definition Debugger.h:728
bool SetShowInlineDiagnostics(bool)
Definition Debugger.cpp:700
bool LoadPlugin(const FileSpec &spec, Status &error)
Definition Debugger.cpp:753
void SetOutputFile(lldb::FileSP file)
uint64_t GetStopSourceLineCount(bool before) const
Definition Debugger.cpp:622
bool SetStatuslineFormat(const FormatEntity::Entry &format)
Definition Debugger.cpp:503
void EnableForwardEvents(const lldb::ListenerSP &listener_sp)
static lldb::DebuggerSP FindDebuggerWithID(lldb::user_id_t id)
void HandleBreakpointEvent(const lldb::EventSP &event_sp)
bool CheckTopIOHandlerTypes(IOHandler::Type top_type, IOHandler::Type second_top_type)
Target & GetDummyTarget()
Definition Debugger.h:508
lldb::ListenerSP GetListener()
Definition Debugger.h:172
static void Destroy(lldb::DebuggerSP &debugger_sp)
Definition Debugger.cpp:885
SourceManager::SourceFileCache m_source_file_cache
Definition Debugger.h:746
ExecutionContextRef GetSelectedExecutionContextRef()
Similar to GetSelectedExecutionContext but returns a ExecutionContextRef, and will hold the dummy tar...
llvm::StringRef GetPromptAnsiPrefix() const
Definition Debugger.cpp:333
lldb::StreamUP GetAsyncOutputStream()
void RedrawStatusline(std::optional< ExecutionContextRef > exe_ctx_ref)
Redraw the statusline if enabled.
void RunIOHandlerSync(const lldb::IOHandlerSP &reader_sp)
Run the given IO handler and block until it's complete.
Broadcaster & GetBroadcaster()
Get the public broadcaster for this debugger.
Definition Debugger.h:87
llvm::StringRef GetStopShowLineMarkerAnsiPrefix() const
Definition Debugger.cpp:610
bool GetShowDontUsePoHint() const
Definition Debugger.cpp:565
uint64_t GetTabSize() const
Definition Debugger.cpp:676
bool GetShowProgress() const
Definition Debugger.cpp:469
llvm::StringRef GetRegexMatchAnsiPrefix() const
Definition Debugger.cpp:553
std::mutex m_output_flush_mutex
Definition Debugger.h:721
llvm::StringRef GetStopShowLineMarkerAnsiSuffix() const
Definition Debugger.cpp:616
bool SetSeparator(llvm::StringRef s)
Definition Debugger.cpp:528
bool SetUseColor(bool use_color)
Definition Debugger.cpp:460
std::mutex m_statusline_mutex
Mutex protecting the m_statusline member.
Definition Debugger.h:761
const char * GetIOHandlerHelpPrologue()
Status SetInputString(const char *data)
bool GetUseAutosuggestion() const
Definition Debugger.cpp:535
Target & GetSelectedOrDummyTarget(bool prefer_dummy=false)
IOHandlerStack m_io_handler_stack
Definition Debugger.h:757
llvm::once_flag m_clear_once
Definition Debugger.h:775
static void SettingsTerminate()
Definition Debugger.cpp:751
static void ReportProgress(uint64_t progress_id, std::string title, std::string details, uint64_t completed, uint64_t total, std::optional< lldb::user_id_t > debugger_id, uint32_t progress_category_bit=lldb::eBroadcastBitProgress)
Report progress events.
lldb::LanguageType GetREPLLanguage() const
Definition Debugger.cpp:378
ScriptInterpreter * GetScriptInterpreter(bool can_create=true, std::optional< lldb::ScriptLanguage > language={})
void SetLoggingCallback(lldb::LogOutputCallback log_callback, void *baton)
bool SetTerminalWidth(uint64_t term_width)
Definition Debugger.cpp:394
Debugger(lldb::LogOutputCallback m_log_callback, void *baton)
Definition Debugger.cpp:965
llvm::StringRef GetExternalEditor() const
Definition Debugger.cpp:443
static size_t GetNumDebuggers()
FormatEntity::Entry GetThreadFormat() const
Definition Debugger.cpp:356
uint32_t m_interrupt_requested
Tracks interrupt requests.
Definition Debugger.h:799
lldb::DWIMPrintVerbosity GetDWIMPrintVerbosity() const
Definition Debugger.cpp:687
lldb::thread_result_t DefaultEventHandler()
void PrintAsync(const char *s, size_t len, bool is_stdout)
lldb::LockableStreamFileSP GetErrorStreamSP()
Definition Debugger.h:682
llvm::StringRef GetPrompt() const
Definition Debugger.cpp:327
bool GetNotifyVoid() const
Definition Debugger.cpp:321
llvm::StringRef GetShowProgressAnsiPrefix() const
Definition Debugger.cpp:480
void AdoptTopIOHandlerFilesIfInvalid(lldb::FileSP &in, lldb::LockableStreamFileSP &out, lldb::LockableStreamFileSP &err)
FormatEntity::Entry GetFrameFormat() const
Definition Debugger.cpp:305
lldb::StopDisassemblyType GetStopDisassemblyDisplay() const
Definition Debugger.cpp:629
llvm::StringRef GetTopIOHandlerControlSequence(char ch)
void FlushProcessOutput(Process &process, bool flush_stdout, bool flush_stderr)
Force flushing the process's pending stdout and stderr to the debugger's asynchronous stdout and stde...
void CancelInterruptRequest()
Decrement the "interrupt requested" counter.
static void ReportDiagnosticImpl(lldb::Severity severity, std::string message, std::optional< lldb::user_id_t > debugger_id, std::once_flag *once)
std::vector< lldb::DebuggerSP > DebuggerList
Definition Debugger.h:82
bool SetAutoIndent(bool b)
Definition Debugger.cpp:660
friend class CommandInterpreter
Definition Debugger.h:628
llvm::StringRef GetStopShowColumnAnsiPrefix() const
Definition Debugger.cpp:598
static DebuggerList DebuggersRequestingInterruption()
void Dump(Stream *s) const override
static const DiagnosticEventData * GetEventDataFromEvent(const Event *event_ptr)
CallbackID AddCallback(Callback callback)
void Report(llvm::StringRef message)
void RemoveCallback(CallbackID id)
static Diagnostics & Instance()
static const void * GetBytesFromEvent(const Event *event_ptr)
Definition Event.cpp:146
static lldb::ProcessSP GetProcessFromEvent(const Event *event_ptr)
Definition Event.cpp:247
static lldb::StructuredDataPluginSP GetPluginFromEvent(const Event *event_ptr)
Definition Event.cpp:265
static StructuredData::ObjectSP GetObjectFromEvent(const Event *event_ptr)
Definition Event.cpp:256
Execution context objects refer to objects in the execution of the program that is being debugged.
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
const lldb::TargetSP & GetTargetSP() const
Get accessor to get the target shared pointer.
bool HasTargetScope() const
Returns true the ExecutionContext object contains a valid target.
Target & GetTargetRef() const
Returns a reference to the target object.
A file utility class.
Definition FileSpec.h:57
FileSpec CopyByAppendingPathComponent(llvm::StringRef component) const
Definition FileSpec.cpp:425
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
Definition FileSpec.cpp:374
llvm::StringRef GetFileNameExtension() const
Extract the extension of the file.
Definition FileSpec.cpp:410
void Resolve(llvm::SmallVectorImpl< char > &path)
Resolve path to make it canonical.
void EnumerateDirectory(llvm::Twine path, bool find_directories, bool find_files, bool find_other, EnumerateDirectoryCallbackType callback, void *callback_baton)
@ eEnumerateDirectoryResultEnter
Recurse into the current entry if it is a directory or symlink, or next if not.
Definition FileSystem.h:181
@ eEnumerateDirectoryResultNext
Enumerate next entry in the current directory.
Definition FileSystem.h:178
@ eEnumerateDirectoryResultQuit
Stop directory enumerations at any level.
Definition FileSystem.h:183
int Open(const char *path, int flags, int mode=0600)
Wraps open in a platform-independent way.
static FileSystem & Instance()
An abstract base class for files.
Definition File.h:36
bool GetIsRealTerminal()
Return true if this file from a real terminal.
Definition File.cpp:200
static int kInvalidDescriptor
Definition File.h:38
virtual int GetDescriptor() const
Get underlying OS file descriptor for this file, or kInvalidDescriptor.
Definition File.cpp:127
bool GetIsTerminalWithColors()
Return true if this file is a terminal which supports colors.
Definition File.cpp:206
Status Close() override
Flush any buffers and release any resources owned by the file.
Definition File.cpp:116
@ eOpenOptionWriteOnly
Definition File.h:52
@ eOpenOptionCanCreate
Definition File.h:56
@ eOpenOptionTruncate
Definition File.h:57
bool GetIsInteractive()
Return true if this file is interactive.
Definition File.cpp:194
const Mangled & GetMangled() const
Definition Function.h:534
static void SystemLog(lldb::Severity severity, llvm::StringRef message)
Emit the given message to the operating system log.
static lldb::thread_t GetCurrentThread()
Get the thread token (the one returned by ThreadCreate when the thread was created) for the calling t...
static llvm::StringRef GetSettingName()
Definition Language.cpp:45
static LanguageSet GetLanguagesSupportingREPLs()
Definition Language.cpp:432
static const char * GetNameForLanguageType(lldb::LanguageType language)
Definition Language.cpp:266
static LanguageProperties & GetGlobalLanguageProperties()
Definition Language.cpp:40
static lldb::ListenerSP MakeListener(const char *name)
Definition Listener.cpp:375
static bool EnableLogChannel(const std::shared_ptr< LogHandler > &log_handler_sp, uint32_t log_options, llvm::StringRef channel, llvm::ArrayRef< const char * > categories, llvm::raw_ostream &error_stream)
Definition Log.cpp:234
static ModuleListProperties & GetGlobalModuleListProperties()
static lldb::PlatformSP GetHostPlatform()
Get the native host platform plug-in.
Definition Platform.cpp:134
static PlatformProperties & GetGlobalPlatformProperties()
Definition Platform.cpp:140
static lldb::ScriptInterpreterSP GetScriptInterpreterForLanguage(lldb::ScriptLanguage script_lang, Debugger &debugger)
static void DebuggerInitialize(Debugger &debugger)
FollowForkMode GetFollowForkMode() const
Definition Process.cpp:368
static lldb::ProcessSP GetProcessFromEvent(const Event *event_ptr)
Definition Process.cpp:4404
static lldb::StateType GetStateFromEvent(const Event *event_ptr)
Definition Process.cpp:4412
A plug-in interface definition class for debugging a process.
Definition Process.h:357
static bool HandleProcessStateChangedEvent(const lldb::EventSP &event_sp, Stream *stream, SelectMostRelevant select_most_relevant, bool &pop_process_io_handler)
Centralize the code that handles and prints descriptions for process state changes.
Definition Process.cpp:733
static llvm::StringRef GetStaticBroadcasterClass()
Definition Process.cpp:422
virtual size_t GetSTDERR(char *buf, size_t buf_size, Status &error)
Get any available STDERR.
Definition Process.cpp:4607
virtual size_t GetSTDOUT(char *buf, size_t buf_size, Status &error)
Get any available STDOUT.
Definition Process.cpp:4588
static const ProgressEventData * GetEventDataFromEvent(const Event *event_ptr)
lldb::OptionValuePropertiesSP m_collection_sp
virtual Status SetPropertyValue(const ExecutionContext *exe_ctx, VarSetOperationType op, llvm::StringRef property_path, llvm::StringRef value)
T GetPropertyAtIndexAs(uint32_t idx, T default_value, const ExecutionContext *exe_ctx=nullptr) const
bool SetPropertyAtIndex(uint32_t idx, T t, const ExecutionContext *exe_ctx=nullptr) const
lldb::OptionValuePropertiesSP GetValueProperties() const
static lldb::REPLSP Create(Status &Status, lldb::LanguageType language, Debugger *debugger, Target *target, const char *repl_options)
Get a REPL with an existing target (or, failing that, a debugger to use), and (optional) extra argume...
Definition REPL.cpp:38
An error handling class.
Definition Status.h:118
static Status FromErrorStringWithFormat(const char *format,...) __attribute__((format(printf
Definition Status.cpp:106
static Status FromErrorString(const char *str)
Definition Status.h:141
bool Success() const
Test for success condition.
Definition Status.cpp:304
void Flush() override
Flush the stream.
llvm::StringRef GetString() const
A stream class that can stream formatted output to a file.
Definition Stream.h:28
size_t Write(const void *src, size_t src_len)
Output character bytes to the stream.
Definition Stream.h:112
size_t PutChar(char ch)
Definition Stream.cpp:131
virtual void Flush()=0
Flush the stream.
Defines a symbol context baton that can be handed other debug core functions.
Function * function
The Function for a given query.
Symbol * symbol
The Symbol for a given query.
bool Compare(ConstString name, lldb::SymbolType type) const
Definition Symbol.cpp:386
ConstString GetName() const
Definition Symbol.cpp:511
lldb::SymbolType GetType() const
Definition Symbol.h:169
@ eBroadcastBitBreakpointChanged
Definition Target.h:534
Debugger & GetDebugger() const
Definition Target.h:1097
static void SettingsTerminate()
Definition Target.cpp:2787
static llvm::StringRef GetStaticBroadcasterClass()
Definition Target.cpp:168
static TargetProperties & GetGlobalProperties()
Definition Target.cpp:3249
static ArchSpec GetDefaultArchitecture()
Definition Target.cpp:2797
static void SettingsInitialize()
Definition Target.cpp:2785
static llvm::Expected< HostThread > LaunchThread(llvm::StringRef name, std::function< lldb::thread_result_t()> thread_function, size_t min_stack_byte_size=0)
static lldb::ThreadSP GetThreadFromEvent(const Event *event_ptr)
Definition Thread.cpp:182
static llvm::StringRef GetStaticBroadcasterClass()
Definition Thread.cpp:214
@ eBroadcastBitThreadSelected
Definition Thread.h:77
virtual void DispatchClientTelemetry(const lldb_private::StructuredDataImpl &entry, Debugger *debugger)
static TelemetryManager * GetInstance()
@ SelectMostRelevantFrame
#define LLDB_INVALID_HOST_THREAD
Definition lldb-types.h:69
Status Parse(const llvm::StringRef &format, Entry &entry)
bool Format(const Entry &entry, Stream &s, const SymbolContext *sc, const ExecutionContext *exe_ctx, const Address *addr, ValueObject *valobj, bool function_changed, bool initial_function)
std::string FormatAnsiTerminalCodes(llvm::StringRef format, bool do_color=true)
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
Definition Log.h:332
LoadScriptFromSymFile
Definition Target.h:54
@ eLoadScriptFromSymFileTrue
Definition Target.h:55
@ eLoadScriptFromSymFileFalse
Definition Target.h:56
@ eLoadScriptFromSymFileWarn
Definition Target.h:57
const char * GetVersion()
Retrieves a string representing the complete LLDB version, which includes the lldb version number,...
Definition Version.cpp:38
void(* DebuggerDestroyCallback)(lldb::user_id_t debugger_id, void *baton)
bool StateIsStoppedState(lldb::StateType state, bool must_exist)
Check if a state represents a state where the process or thread is stopped.
Definition State.cpp:89
llvm::sys::DynamicLibrary(* LoadPluginCallbackType)(const lldb::DebuggerSP &debugger_sp, const FileSpec &spec, Status &error)
VarSetOperationType
Settable state variable types.
ScriptLanguage
Script interpreter types.
@ eScriptLanguageDefault
@ eScriptLanguageNone
@ eScriptLanguagePython
Severity
Used for expressing severity in logs and diagnostics.
@ eBroadcastBitExternalProgress
@ eBroadcastBitProgress
@ eBroadcastSymbolChange
std::shared_ptr< lldb_private::IOHandler > IOHandlerSP
std::shared_ptr< lldb_private::Thread > ThreadSP
void * thread_result_t
Definition lldb-types.h:62
std::shared_ptr< lldb_private::Platform > PlatformSP
DWIMPrintVerbosity
Enum to control the verbosity level of dwim-print execution.
@ eDWIMPrintVerbosityFull
Always print a message indicating how dwim-print is evaluating its expression.
@ eDWIMPrintVerbosityNone
Run dwim-print with no verbosity.
@ eDWIMPrintVerbosityExpression
Print a message when dwim-print uses expression evaluation.
StateType
Process and Thread States.
LanguageType
Programming language type.
@ eLanguageTypeUnknown
Unknown or invalid language value.
std::shared_ptr< lldb_private::Breakpoint > BreakpointSP
std::shared_ptr< lldb_private::StructuredDataPlugin > StructuredDataPluginSP
std::shared_ptr< lldb_private::Process > ProcessSP
std::shared_ptr< lldb_private::Debugger > DebuggerSP
StopDisassemblyType
Used to determine when to show disassembly.
@ eStopDisassemblyTypeNever
@ eStopDisassemblyTypeNoSource
@ eStopDisassemblyTypeAlways
@ eStopDisassemblyTypeNoDebugInfo
@ eStopShowColumnAnsi
@ eStopShowColumnCaret
@ eStopShowColumnNone
@ eStopShowColumnAnsiOrCaret
std::shared_ptr< lldb_private::Event > EventSP
uint64_t pid_t
Definition lldb-types.h:83
std::shared_ptr< lldb_private::Listener > ListenerSP
int32_t callback_token_t
Definition lldb-types.h:81
uint64_t user_id_t
Definition lldb-types.h:82
std::shared_ptr< lldb_private::LockableStreamFile > LockableStreamFileSP
void(* LogOutputCallback)(const char *, void *baton)
Definition lldb-types.h:73
std::shared_ptr< lldb_private::Target > TargetSP
std::unique_ptr< lldb_private::Stream > StreamUP
std::shared_ptr< lldb_private::File > FileSP
std::shared_ptr< lldb_private::REPL > REPLSP
lldb_private::DebuggerDestroyCallback callback
Definition Debugger.h:794
A SmallBitVector that represents a set of source languages (lldb::LanguageType).
Definition Type.h:38
std::optional< lldb::LanguageType > GetSingularLanguage()
If the set contains a single language only, return it.
UserID(lldb::user_id_t uid=LLDB_INVALID_UID)
Construct with optional user ID.
Definition UserID.h:33
lldb::user_id_t GetID() const
Get accessor for the user ID.
Definition UserID.h:47
Helper RAII class for collecting telemetry.
Definition Telemetry.h:269
#define PATH_MAX