61#include "llvm/ADT/STLExtras.h"
62#include "llvm/ADT/StringRef.h"
63#include "llvm/ADT/iterator.h"
64#include "llvm/Support/DynamicLibrary.h"
65#include "llvm/Support/FileSystem.h"
66#include "llvm/Support/Process.h"
67#include "llvm/Support/ThreadPool.h"
68#include "llvm/Support/Threading.h"
69#include "llvm/Support/raw_ostream.h"
80#include <system_error>
100#pragma mark Static Functions
113 "Never show disassembly when displaying a stop context.",
118 "Show disassembly when there is no debug information.",
123 "Show disassembly when there is no source information, or the source "
125 "is missing when displaying a stop context.",
130 "Always show disassembly when displaying a stop context.",
138 "Disable scripting languages.",
143 "Select python as the default scripting language.",
148 "Select the lldb default as the default scripting language.",
154 "Use no verbosity when running dwim-print."},
156 "Use partial verbosity when running dwim-print - display a message when "
157 "`expression` evaluation is used."},
159 "Use full verbosity when running dwim-print."},
166 "Highlight the stop column with ANSI terminal codes when color/ANSI "
167 "mode is enabled; otherwise, fall back to using a text-only caret (^) "
168 "as if \"caret-only\" mode was selected.",
173 "Highlight the stop column with ANSI terminal codes when running LLDB "
174 "with color/ANSI enabled.",
179 "Highlight the stop column with a caret character (^) underneath the "
180 "stop column. This method introduces a new line in source listings "
181 "that display thread stop locations.",
186 "Do not highlight the stop column.",
190#define LLDB_PROPERTIES_debugger
191#include "CoreProperties.inc"
194#define LLDB_PROPERTIES_debugger
195#include "CorePropertiesEnum.inc"
202 llvm::StringRef property_path,
203 llvm::StringRef value) {
204 bool is_load_script =
205 (property_path ==
"target.load-script-from-symbol-file");
207 bool invalidate_data_vis = (property_path ==
"escape-non-printables");
208 invalidate_data_vis |=
209 (property_path ==
"target.max-zero-padding-in-float-format");
210 if (invalidate_data_vis) {
218 load_script_old_value =
219 target_sp->TargetProperties::GetLoadScriptFromSymbolFile();
222 if (
error.Success()) {
224 if (property_path == g_debugger_properties[ePropertyPrompt].name) {
225 llvm::StringRef new_prompt =
GetPrompt();
231 auto bytes = std::make_unique<EventDataBytes>(new_prompt);
232 auto prompt_change_event_sp = std::make_shared<Event>(
235 }
else if (property_path == g_debugger_properties[ePropertyUseColor].name) {
239 }
else if (property_path == g_debugger_properties[ePropertyUseSourceCache].name) {
244 }
else if (is_load_script && target_sp &&
246 if (target_sp->TargetProperties::GetLoadScriptFromSymbolFile() ==
248 std::list<Status> errors;
250 if (!target_sp->LoadScriptingResources(errors, &feedback_stream)) {
252 for (
auto error : errors) {
265 constexpr uint32_t idx = ePropertyAutoConfirm;
266 return GetPropertyAtIndexAs<bool>(
267 idx, g_debugger_properties[idx].default_uint_value != 0);
271 constexpr uint32_t idx = ePropertyDisassemblyFormat;
272 return GetPropertyAtIndexAs<const FormatEntity::Entry *>(idx);
276 constexpr uint32_t idx = ePropertyFrameFormat;
277 return GetPropertyAtIndexAs<const FormatEntity::Entry *>(idx);
281 constexpr uint32_t idx = ePropertyFrameFormatUnique;
282 return GetPropertyAtIndexAs<const FormatEntity::Entry *>(idx);
286 constexpr uint32_t idx = ePropertyStopDisassemblyMaxSize;
287 return GetPropertyAtIndexAs<uint64_t>(
288 idx, g_debugger_properties[idx].default_uint_value);
292 constexpr uint32_t idx = ePropertyNotiftVoid;
293 return GetPropertyAtIndexAs<uint64_t>(
294 idx, g_debugger_properties[idx].default_uint_value != 0);
298 constexpr uint32_t idx = ePropertyPrompt;
299 return GetPropertyAtIndexAs<llvm::StringRef>(
300 idx, g_debugger_properties[idx].default_cstr_value);
304 constexpr uint32_t idx = ePropertyPrompt;
306 llvm::StringRef new_prompt =
GetPrompt();
315 constexpr uint32_t idx = ePropertyThreadFormat;
316 return GetPropertyAtIndexAs<const FormatEntity::Entry *>(idx);
320 constexpr uint32_t idx = ePropertyThreadStopFormat;
321 return GetPropertyAtIndexAs<const FormatEntity::Entry *>(idx);
325 const uint32_t idx = ePropertyScriptLanguage;
326 return GetPropertyAtIndexAs<lldb::ScriptLanguage>(
328 g_debugger_properties[idx].default_uint_value));
332 const uint32_t idx = ePropertyScriptLanguage;
337 const uint32_t idx = ePropertyREPLLanguage;
338 return GetPropertyAtIndexAs<LanguageType>(idx, {});
342 const uint32_t idx = ePropertyREPLLanguage;
347 const uint32_t idx = ePropertyTerminalWidth;
348 return GetPropertyAtIndexAs<int64_t>(
349 idx, g_debugger_properties[idx].default_uint_value);
354 handler_sp->TerminalSizeChanged();
356 const uint32_t idx = ePropertyTerminalWidth;
361 const uint32_t idx = ePropertyUseExternalEditor;
362 return GetPropertyAtIndexAs<bool>(
363 idx, g_debugger_properties[idx].default_uint_value != 0);
367 const uint32_t idx = ePropertyUseExternalEditor;
372 const uint32_t idx = ePropertyExternalEditor;
373 return GetPropertyAtIndexAs<llvm::StringRef>(
374 idx, g_debugger_properties[idx].default_cstr_value);
378 const uint32_t idx = ePropertyExternalEditor;
383 const uint32_t idx = ePropertyUseColor;
384 return GetPropertyAtIndexAs<bool>(
385 idx, g_debugger_properties[idx].default_uint_value != 0);
389 const uint32_t idx = ePropertyUseColor;
396 const uint32_t idx = ePropertyShowProgress;
397 return GetPropertyAtIndexAs<bool>(
398 idx, g_debugger_properties[idx].default_uint_value != 0);
402 const uint32_t idx = ePropertyShowProgress;
407 const uint32_t idx = ePropertyShowProgressAnsiPrefix;
408 return GetPropertyAtIndexAs<llvm::StringRef>(
409 idx, g_debugger_properties[idx].default_cstr_value);
413 const uint32_t idx = ePropertyShowProgressAnsiSuffix;
414 return GetPropertyAtIndexAs<llvm::StringRef>(
415 idx, g_debugger_properties[idx].default_cstr_value);
419 const uint32_t idx = ePropertyShowAutosuggestion;
420 return GetPropertyAtIndexAs<bool>(
421 idx, g_debugger_properties[idx].default_uint_value != 0);
425 const uint32_t idx = ePropertyShowAutosuggestionAnsiPrefix;
426 return GetPropertyAtIndexAs<llvm::StringRef>(
427 idx, g_debugger_properties[idx].default_cstr_value);
431 const uint32_t idx = ePropertyShowAutosuggestionAnsiSuffix;
432 return GetPropertyAtIndexAs<llvm::StringRef>(
433 idx, g_debugger_properties[idx].default_cstr_value);
437 const uint32_t idx = ePropertyUseSourceCache;
438 return GetPropertyAtIndexAs<bool>(
439 idx, g_debugger_properties[idx].default_uint_value != 0);
443 const uint32_t idx = ePropertyUseSourceCache;
451 const uint32_t idx = ePropertyHighlightSource;
452 return GetPropertyAtIndexAs<bool>(
453 idx, g_debugger_properties[idx].default_uint_value != 0);
457 const uint32_t idx = ePropertyStopShowColumn;
458 return GetPropertyAtIndexAs<lldb::StopShowColumn>(
460 g_debugger_properties[idx].default_uint_value));
464 const uint32_t idx = ePropertyStopShowColumnAnsiPrefix;
465 return GetPropertyAtIndexAs<llvm::StringRef>(
466 idx, g_debugger_properties[idx].default_cstr_value);
470 const uint32_t idx = ePropertyStopShowColumnAnsiSuffix;
471 return GetPropertyAtIndexAs<llvm::StringRef>(
472 idx, g_debugger_properties[idx].default_cstr_value);
476 const uint32_t idx = ePropertyStopShowLineMarkerAnsiPrefix;
477 return GetPropertyAtIndexAs<llvm::StringRef>(
478 idx, g_debugger_properties[idx].default_cstr_value);
482 const uint32_t idx = ePropertyStopShowLineMarkerAnsiSuffix;
483 return GetPropertyAtIndexAs<llvm::StringRef>(
484 idx, g_debugger_properties[idx].default_cstr_value);
489 before ? ePropertyStopLineCountBefore : ePropertyStopLineCountAfter;
490 return GetPropertyAtIndexAs<uint64_t>(
491 idx, g_debugger_properties[idx].default_uint_value);
495 const uint32_t idx = ePropertyStopDisassemblyDisplay;
496 return GetPropertyAtIndexAs<Debugger::StopDisassemblyType>(
498 g_debugger_properties[idx].default_uint_value));
502 const uint32_t idx = ePropertyStopDisassemblyCount;
503 return GetPropertyAtIndexAs<uint64_t>(
504 idx, g_debugger_properties[idx].default_uint_value);
508 const uint32_t idx = ePropertyAutoOneLineSummaries;
509 return GetPropertyAtIndexAs<bool>(
510 idx, g_debugger_properties[idx].default_uint_value != 0);
514 const uint32_t idx = ePropertyEscapeNonPrintables;
515 return GetPropertyAtIndexAs<bool>(
516 idx, g_debugger_properties[idx].default_uint_value != 0);
520 const uint32_t idx = ePropertyAutoIndent;
521 return GetPropertyAtIndexAs<bool>(
522 idx, g_debugger_properties[idx].default_uint_value != 0);
526 const uint32_t idx = ePropertyAutoIndent;
531 const uint32_t idx = ePropertyPrintDecls;
532 return GetPropertyAtIndexAs<bool>(
533 idx, g_debugger_properties[idx].default_uint_value != 0);
537 const uint32_t idx = ePropertyPrintDecls;
542 const uint32_t idx = ePropertyTabSize;
543 return GetPropertyAtIndexAs<uint64_t>(
544 idx, g_debugger_properties[idx].default_uint_value);
548 const uint32_t idx = ePropertyTabSize;
553 const uint32_t idx = ePropertyDWIMPrintVerbosity;
554 return GetPropertyAtIndexAs<lldb::DWIMPrintVerbosity>(
556 g_debugger_properties[idx].default_uint_value));
570 "Debugger::Initialize called more than once!");
573 g_thread_pool =
new llvm::ThreadPool(llvm::optimal_concurrency());
579 "Debugger::Terminate called without a matching Debugger::Initialize!");
584 debugger->HandleDestroyCallback();
609 llvm::sys::DynamicLibrary dynlib =
611 if (dynlib.isValid()) {
619 error.SetErrorString(
"Public API layer is not available");
626 llvm::StringRef path) {
629 static constexpr llvm::StringLiteral g_dylibext(
".dylib");
630 static constexpr llvm::StringLiteral g_solibext(
".so");
637 namespace fs = llvm::sys::fs;
642 if (ft == fs::file_type::regular_file || ft == fs::file_type::symlink_file ||
643 ft == fs::file_type::type_unknown) {
653 debugger->
LoadPlugin(plugin_file_spec, plugin_load_error);
656 }
else if (ft == fs::file_type::directory_file ||
657 ft == fs::file_type::symlink_file ||
658 ft == fs::file_type::type_unknown) {
670 const bool find_directories =
true;
671 const bool find_files =
true;
672 const bool find_other =
true;
674 if (
FileSpec dir_spec = HostInfo::GetSystemPluginDir()) {
676 dir_spec.GetPath(dir_path,
sizeof(dir_path))) {
678 find_files, find_other,
683 if (
FileSpec dir_spec = HostInfo::GetUserPluginDir()) {
685 dir_spec.GetPath(dir_path,
sizeof(dir_path))) {
687 find_files, find_other,
697 DebuggerSP debugger_sp(
new Debugger(log_callback, baton));
702 debugger_sp->InstanceInitialize();
717 debugger_sp->HandleDestroyCallback();
724 (*debugger_sp->GetAsyncOutputStream()) << result.
GetOutputData() <<
'\n';
726 (*debugger_sp->GetAsyncErrorStream()) << result.
GetErrorData() <<
'\n';
729 debugger_sp->Clear();
735 if ((*pos).get() == debugger_sp.get()) {
753 if (llvm::StringRef(debugger_sp->GetInstanceName()) == instance_name)
765 target_sp = (*pos)->GetTargetList().FindTargetWithProcessID(pid);
779 target_sp = (*pos)->GetTargetList().FindTargetWithProcess(process);
795 m_input_file_sp(std::make_shared<
NativeFile>(stdin, false)),
796 m_output_stream_sp(std::make_shared<
StreamFile>(stdout, false)),
797 m_error_stream_sp(std::make_shared<
StreamFile>(stderr, false)),
798 m_input_recorder(nullptr),
800 m_terminal_state(), m_target_list(*this), m_platform_list(),
801 m_listener_sp(
Listener::MakeListener(
"lldb.Debugger")),
802 m_source_manager_up(), m_source_file_cache(),
803 m_command_interpreter_up(
805 m_io_handler_stack(),
806 m_instance_name(
llvm::formatv(
"debugger_{0}", GetID()).str()),
807 m_loaded_plugins(), m_event_handler_thread(), m_io_handler_thread(),
808 m_sync_broadcaster(nullptr,
"lldb.debugger.sync"),
809 m_broadcaster(m_broadcaster_manager_sp,
810 GetStaticBroadcasterClass().AsCString()),
811 m_forward_listener_sp(), m_clear_once() {
816 ConstString(
"target"),
"Settings specify to debugging targets.",
true,
819 ConstString(
"platform"),
"Platform settings.",
true,
822 ConstString(
"symbols"),
"Symbol lookup and cache settings.",
true,
827 "Settings specify to the debugger's command interpreter.",
true,
832 std::make_shared<CallbackLogHandler>(log_callback, baton);
836 assert(default_platform_sp);
843 arch = HostInfo::GetArchitecture();
844 assert(arch.
IsValid() &&
"No valid default or host archspec");
845 const bool is_dummy_target =
true;
847 new Target(*
this, arch, default_platform_sp, is_dummy_target));
853 ePropertyTerminalWidth);
858 const char *term = getenv(
"TERM");
859 if (term && !strcmp(term,
"dumb"))
867 [
this](
const FileSpec &dir) -> llvm::Error {
869 llvm::StringRef log_path = entry.first();
870 llvm::StringRef file_name = llvm::sys::path::filename(log_path);
873 llvm::sys::fs::copy_file(log_path, destination.
GetPath());
875 return llvm::errorCodeToError(ec);
877 return llvm::Error::success();
881#if defined(_WIN32) && defined(ENABLE_VIRTUAL_TERMINAL_PROCESSING)
884 llvm::sys::Process::UseANSIEscapeCodes(
true);
906 if (ProcessSP process_sp = target_sp->GetProcessSP())
907 process_sp->Finalize();
908 target_sp->Destroy();
944static inline int OpenPipe(
int fds[2], std::size_t size) {
946 return _pipe(fds, size, O_BINARY);
956 int fds[2] = {-1, -1};
958 if (data ==
nullptr) {
963 size_t size = strlen(data);
971 "can't create pipe file descriptors for LLDB commands");
975 int r = write(fds[
WRITE], data, size);
979 llvm::sys::Process::SafelyCloseFileDescriptor(fds[
WRITE]);
983 FILE *commands_file = fdopen(fds[
READ],
"rb");
984 if (commands_file ==
nullptr) {
986 "when trying to open LLDB commands pipe",
988 llvm::sys::Process::SafelyCloseFileDescriptor(fds[
READ]);
992 SetInputFile((FileSP)std::make_shared<NativeFile>(commands_file,
true));
997 assert(file_sp && file_sp->IsValid());
1005 assert(file_sp && file_sp->IsValid());
1010 assert(file_sp && file_sp->IsValid());
1023 bool adopt_selected =
true;
1032 reader_sp->Interrupt();
1039 reader_sp->GotEOF();
1061 std::lock_guard<std::recursive_mutex> guard(
1067 if (top_reader_sp && top_reader_sp->GetIsDone())
1082 IOHandlerSP top_reader_sp = reader_sp;
1084 while (top_reader_sp) {
1088 top_reader_sp->Run();
1091 if (top_reader_sp.get() == reader_sp.get()) {
1100 if (top_reader_sp && top_reader_sp->GetIsDone()) {
1103 if (top_reader_sp.get() == reader_sp.get())
1124 lldb::StreamFileSP stream =
1126 stream->Write(s, len);
1147 bool cancel_top_handler) {
1152 StreamFileSP &err) {
1161 if (!in || !in->IsValid()) {
1163 in = top_reader_sp->GetInputFileSP();
1168 in = std::make_shared<NativeFile>(stdin,
false);
1171 if (!out || !out->GetFile().IsValid()) {
1173 out = top_reader_sp->GetOutputStreamFileSP();
1178 out = std::make_shared<StreamFile>(stdout,
false);
1181 if (!err || !err->GetFile().IsValid()) {
1183 err = top_reader_sp->GetErrorStreamFileSP();
1188 err = std::make_shared<StreamFile>(stderr,
false);
1193 bool cancel_top_handler) {
1203 if (reader_sp == top_reader_sp)
1208 reader_sp->Activate();
1212 if (top_reader_sp) {
1213 top_reader_sp->Deactivate();
1214 if (cancel_top_handler)
1215 top_reader_sp->Cancel();
1232 if (pop_reader_sp != reader_sp)
1235 reader_sp->Deactivate();
1236 reader_sp->Cancel();
1241 reader_sp->Activate();
1247 return std::make_shared<StreamAsynchronousIO>(*
this,
true,
GetUseColor());
1251 return std::make_shared<StreamAsynchronousIO>(*
this,
false,
GetUseColor());
1286 DebuggerSP debugger_sp;
1290 if (index < g_debugger_list_ptr->size())
1298 DebuggerSP debugger_sp;
1304 if ((*pos)->GetID() ==
id) {
1320 if (format ==
nullptr) {
1323 if (format ==
nullptr) {
1325 format = &format_entry;
1328 bool function_changed =
false;
1329 bool initial_function =
false;
1335 function_changed =
true;
1339 function_changed =
true;
1349 initial_function =
true;
1352 function_changed, initial_function);
1361 std::make_shared<CallbackLogHandler>(log_callback, baton);
1365 lldb_private::DebuggerDestroyCallback destroy_callback,
void *baton) {
1371 std::string title, std::string details,
1372 uint64_t completed, uint64_t total,
1373 bool is_debugger_specific) {
1378 EventSP event_sp(
new Event(
1381 completed, total, is_debugger_specific)));
1386 std::string details, uint64_t completed,
1388 std::optional<lldb::user_id_t> debugger_id) {
1396 std::move(details), completed, total,
1413 std::string message,
1414 bool debugger_specific) {
1418 assert(
false &&
"DiagnosticEventData::Type::Info should not be broadcast");
1434 event_data.
Dump(stream.get());
1437 EventSP event_sp = std::make_shared<Event>(
1444 std::string message,
1445 std::optional<lldb::user_id_t> debugger_id,
1446 std::once_flag *once) {
1447 auto ReportDiagnosticLambda = [&]() {
1476 std::call_once(*once, ReportDiagnosticLambda);
1478 ReportDiagnosticLambda();
1482 std::optional<lldb::user_id_t> debugger_id,
1483 std::once_flag *once) {
1489 std::optional<lldb::user_id_t> debugger_id,
1490 std::once_flag *once) {
1496 std::optional<lldb::user_id_t> debugger_id,
1497 std::once_flag *once) {
1506 EventSP event_sp = std::make_shared<Event>(
1509 debugger_sp->GetBroadcaster().BroadcastEvent(event_sp);
1514static std::shared_ptr<LogHandler>
1516 size_t buffer_size) {
1517 switch (log_handler_kind) {
1519 return std::make_shared<StreamLogHandler>(fd, should_close, buffer_size);
1521 return std::make_shared<RotatingLogHandler>(buffer_size);
1523 return std::make_shared<SystemLogHandler>();
1531 llvm::ArrayRef<const char *> categories,
1532 llvm::StringRef log_file,
uint32_t log_options,
1534 llvm::raw_ostream &error_stream) {
1536 std::shared_ptr<LogHandler> log_handler_sp;
1542 }
else if (log_file.empty()) {
1545 false, buffer_size);
1549 log_handler_sp = pos->second.lock();
1550 if (!log_handler_sp) {
1558 FileSpec(log_file), flags, lldb::eFilePermissionsFileDefault,
false);
1560 error_stream <<
"Unable to open log file '" << log_file
1561 <<
"': " << llvm::toString(file.takeError()) <<
"\n";
1571 assert(log_handler_sp);
1573 if (log_options == 0)
1582 std::optional<lldb::ScriptLanguage> language) {
1605 using namespace lldb;
1623 if (event_type & eBreakpointEventTypeLocationsAdded) {
1627 if (num_new_locations > 0) {
1628 BreakpointSP breakpoint =
1632 output_sp->Printf(
"%d location%s added to breakpoint %d\n",
1633 num_new_locations, num_new_locations == 1 ?
"" :
"s",
1634 breakpoint->GetID());
1652 bool flush_stderr) {
1653 const auto &flush = [&](
Stream &stream,
1658 while ((len = (process.*get)(buffer,
sizeof(buffer),
error)) > 0)
1659 stream.
Write(buffer, len);
1672 using namespace lldb;
1673 const uint32_t event_type = event_sp->GetType();
1674 ProcessSP process_sp =
1684 bool pop_process_io_handler =
false;
1687 bool state_is_stopped =
false;
1688 const bool got_state_changed =
1692 const bool got_structured_data =
1695 if (got_state_changed) {
1702 if (got_state_changed && !state_is_stopped) {
1707 pop_process_io_handler);
1712 got_stderr || got_state_changed);
1715 if (got_structured_data) {
1716 StructuredDataPluginSP plugin_sp =
1719 auto structured_data_sp =
1721 if (output_stream_sp) {
1724 plugin_sp->GetDescription(structured_data_sp, content_stream);
1725 if (
error.Success()) {
1726 if (!content_stream.
GetString().empty()) {
1729 content_stream.
Flush();
1732 output_stream_sp->PutCString(content_stream.
GetString());
1735 error_stream_sp->Format(
"Failed to print structured "
1736 "data with plugin {0}: {1}",
1737 plugin_sp->GetPluginName(),
error);
1744 if (got_state_changed && state_is_stopped) {
1747 pop_process_io_handler);
1750 output_stream_sp->Flush();
1751 error_stream_sp->Flush();
1753 if (pop_process_io_handler)
1754 process_sp->PopProcessIOHandler();
1761 using namespace lldb;
1762 const uint32_t event_type = event_sp->GetType();
1763 const bool stop_format =
true;
1793 broadcaster_class_process,
1804 process_event_spec);
1807 listener_sp->StartListeningForEvents(
1813 listener_sp->StartListeningForEvents(
1824 if (listener_sp->GetEvent(event_sp, std::nullopt)) {
1826 Broadcaster *broadcaster = event_sp->GetBroadcaster();
1828 uint32_t event_type = event_sp->GetType();
1830 if (broadcaster_class == broadcaster_class_process) {
1832 }
else if (broadcaster_class == broadcaster_class_target) {
1837 }
else if (broadcaster_class == broadcaster_class_thread) {
1843 }
else if (event_type &
1845 const char *data =
static_cast<const char *
>(
1847 if (data && data[0]) {
1850 error_sp->PutCString(data);
1855 eBroadcastBitAsynchronousOutputData) {
1856 const char *data =
static_cast<const char *
>(
1858 if (data && data[0]) {
1861 output_sp->PutCString(data);
1890 ConstString full_name(
"lldb.debugger.event-handler");
1895 llvm::StringRef thread_name =
1896 full_name.
GetLength() < llvm::get_max_thread_name_length()
1898 :
"dbg.evt-handler";
1901 llvm::Expected<HostThread> event_handler_thread =
1906 if (event_handler_thread) {
1910 llvm::toString(event_handler_thread.takeError()));
1918 lldb::EventSP event_sp;
1919 listener_sp->GetEvent(event_sp, std::nullopt);
1945 const uint64_t
id = data->GetID();
1951 <<
static_cast<void *
>(
this) <<
" Debugger(" <<
GetID()
1952 <<
")::HandleProgressEvent( m_current_event_id = "
1954 data->Dump(&log_stream);
1955 log_stream <<
" } )";
1960 if (data->GetCompleted() == data->GetTotal())
1981 output->Printf(
"\r");
1983 if (data->GetCompleted() == data->GetTotal()) {
1985 output->Printf(
"\x1B[2K");
1991 std::string message = data->GetMessage();
1992 if (data->IsFinite())
1993 message = llvm::formatv(
"[{0}/{1}] {2}", data->GetCompleted(),
1994 data->GetTotal(), message)
2000 if (message.size() + ellipsis >= term_width)
2001 message = message.substr(0, term_width - ellipsis);
2005 if (!ansi_prefix.empty())
2009 output->Printf(
"%s...", message.c_str());
2012 if (!ansi_suffix.empty())
2017 output->Printf(
"\x1B[K\r");
2029 data->Dump(stream.get());
2047 if (io_handler_thread) {
2051 llvm::toString(io_handler_thread.takeError()));
2079 if (!prefer_dummy) {
2097 language = *single_lang;
2098 }
else if (repl_languages.
Empty()) {
2100 "LLDB isn't configured with REPL support for any languages.");
2104 "Multiple possible REPL languages. Please specify a language.");
2112 REPLSP repl_sp(
REPL::Create(err, language,
this, target, repl_options));
2124 repl_sp->SetCompilerOptions(repl_options);
2132 "Debugger::GetThreadPool called before Debugger::Initialize");
static llvm::raw_ostream & error(Stream &strm)
static void PrivateReportDiagnostic(Debugger &debugger, DiagnosticEventData::Type type, std::string message, bool debugger_specific)
static std::recursive_mutex * g_debugger_list_mutex_ptr
static constexpr OptionEnumValueElement g_show_disassembly_enum_values[]
static DebuggerList * g_debugger_list_ptr
static lldb::user_id_t g_unique_id
static constexpr OptionEnumValueElement g_language_enumerators[]
static constexpr OptionEnumValueElement g_dwim_print_verbosities[]
static constexpr OptionEnumValueElement s_stop_show_column_values[]
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)
static int OpenPipe(int fds[2], std::size_t size)
static size_t g_debugger_event_thread_stack_bytes
static FileSystem::EnumerateDirectoryResult LoadPluginCallback(void *baton, llvm::sys::fs::file_type ft, llvm::StringRef path)
static std::shared_ptr< LogHandler > CreateLogHandler(LogHandlerKind log_handler_kind, int fd, bool should_close, size_t buffer_size)
static llvm::ThreadPool * g_thread_pool
std::vector< DebuggerSP > DebuggerList
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
#define LLDB_LOG_OPTION_APPEND
#define LLDB_LOG_OPTION_PREPEND_TIMESTAMP
#define LLDB_LOG_OPTION_PREPEND_THREAD_NAME
A section + offset based address class.
An architecture specification class.
bool IsValid() const
Tests if this ArchSpec is valid.
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)
An event broadcasting class.
bool EventTypeHasListeners(uint32_t event_type)
virtual ConstString & 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 WasInterrupted() const
bool SaveTranscript(CommandReturnObject &result, std::optional< std::string > output_file=std::nullopt)
Save the current debugger session transcript to a file on disk.
@ eBroadcastBitAsynchronousOutputData
@ eBroadcastBitQuitCommandReceived
@ eBroadcastBitAsynchronousErrorData
@ eBroadcastBitResetPrompt
bool GetSaveSessionOnQuit() const
llvm::StringRef GetErrorData()
llvm::StringRef GetOutputData()
A uniqued constant string class.
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.
static void ForceUpdate()
A class to manage flag bits.
llvm::StringRef GetAutosuggestionAnsiPrefix() const
repro::DataRecorder * GetInputRecorder()
lldb::StreamFileSP m_error_stream_sp
bool SetUseExternalEditor(bool use_external_editor_p)
PlatformList m_platform_list
HostThread m_event_handler_thread
static lldb::TargetSP FindTargetWithProcessID(lldb::pid_t pid)
static llvm::ThreadPool & GetThreadPool()
Shared thread poll. Use only with ThreadPoolTaskGroup.
uint64_t GetDisassemblyLineCount() const
lldb::TargetSP GetSelectedTarget()
bool SetExternalEditor(llvm::StringRef editor)
void RequestInterrupt()
Interruption in LLDB:
ExecutionContext GetSelectedExecutionContext()
void HandleProgressEvent(const lldb::EventSP &event_sp)
SourceManager & GetSourceManager()
bool SetShowProgress(bool show_progress)
lldb::StreamSP GetAsyncOutputStream()
bool StartEventHandlerThread()
Manually start the global event handler thread.
bool SetUseSourceCache(bool use_source_cache)
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
lldb::FileSP GetInputFileSP()
void StopIOHandlerThread()
bool GetHighlightSource() const
llvm::StringMap< std::weak_ptr< LogHandler > > m_stream_handlers
CommandInterpreter & GetCommandInterpreter()
void SaveInputTerminalState()
LoadedPluginsList m_loaded_plugins
void InstanceInitialize()
bool SetTabSize(uint64_t tab_size)
void HandleDiagnosticEvent(const lldb::EventSP &event_sp)
bool StartIOHandlerThread()
static lldb::DebuggerSP GetDebuggerAtIndex(size_t index)
llvm::StringRef GetAutosuggestionAnsiSuffix() const
StreamFile & GetErrorStream()
lldb::ListenerSP m_listener_sp
void PushIOHandler(const lldb::IOHandlerSP &reader_sp, bool cancel_top_handler=true)
lldb::thread_result_t IOHandlerThread()
static lldb::TargetSP FindTargetWithProcess(Process *process)
bool GetUseExternalEditor() const
TerminalState m_terminal_state
static void ReportDiagnosticImpl(DiagnosticEventData::Type type, std::string message, std::optional< lldb::user_id_t > debugger_id, std::once_flag *once)
const FormatEntity::Entry * GetThreadStopFormat() const
bool InterruptRequested()
This is the correct way to query the state of Interruption.
bool GetEscapeNonPrintables() const
lldb::TargetSP m_dummy_target_sp
std::unique_ptr< CommandInterpreter > m_command_interpreter_up
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()
llvm::StringRef GetShowProgressAnsiSuffix() const
bool IsTopIOHandler(const lldb::IOHandlerSP &reader_sp)
bool HasIOHandlerThread() const
void DispatchInputEndOfFile()
bool IsIOHandlerThreadCurrentThread() const
lldb::ListenerSP m_forward_listener_sp
std::array< lldb::ScriptInterpreterSP, lldb::eScriptLanguageUnknown > m_script_interpreters
std::shared_ptr< CallbackLogHandler > m_callback_handler_sp
void SetDestroyCallback(lldb_private::DebuggerDestroyCallback destroy_callback, void *baton)
void * m_destroy_callback_baton
StopDisassemblyType GetStopDisassemblyDisplay() const
Broadcaster m_broadcaster
Public Debugger event broadcaster.
void DispatchInputInterrupt()
static void Initialize(LoadPluginCallbackType load_plugin_callback)
static lldb::DebuggerSP FindDebuggerWithInstanceName(llvm::StringRef instance_name)
uint64_t GetTerminalWidth() const
std::mutex m_interrupt_mutex
std::recursive_mutex m_io_handler_synchronous_mutex
bool RemoveIOHandler(const lldb::IOHandlerSP &reader_sp)
Remove the given IO handler if it's currently active.
Diagnostics::CallbackID m_diagnostics_callback_id
bool GetAutoOneLineSummaries() const
const char * GetIOHandlerCommandPrefix()
lldb::BroadcasterManagerSP m_broadcaster_manager_sp
void SetCloseInputOnEOF(bool b)
bool GetCloseInputOnEOF() const
Status RunREPL(lldb::LanguageType language, const char *repl_options)
bool PopIOHandler(const lldb::IOHandlerSP &reader_sp)
static LoadPluginCallbackType g_load_plugin_callback
std::recursive_mutex m_script_interpreter_mutex
ConstString GetTopIOHandlerControlSequence(char ch)
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::StreamFileSP GetErrorStreamSP()
void SetPrompt(llvm::StringRef p)
lldb::StreamSP GetAsyncErrorStream()
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
Broadcaster m_sync_broadcaster
Private debugger synchronization.
void RestoreInputTerminalState()
bool GetUseSourceCache() const
HostThread m_io_handler_thread
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)
Report progress events.
lldb::FileSP m_input_file_sp
bool SetREPLLanguage(lldb::LanguageType repl_lang)
const FormatEntity::Entry * GetDisassemblyFormat() const
bool GetAutoIndent() const
llvm::StringRef GetStopShowColumnAnsiSuffix() const
@ eStopDisassemblyTypeNever
@ eStopDisassemblyTypeNoDebugInfo
@ eStopDisassemblyTypeNoSource
@ eStopDisassemblyTypeAlways
Status SetPropertyValue(const ExecutionContext *exe_ctx, VarSetOperationType op, llvm::StringRef property_path, llvm::StringRef value) override
void SetErrorFile(lldb::FileSP file)
bool GetAutoConfirm() const
lldb::ScriptLanguage GetScriptLanguage() const
std::unique_ptr< SourceManager > m_source_manager_up
static lldb::DebuggerSP CreateInstance(lldb::LogOutputCallback log_callback=nullptr, void *baton=nullptr)
lldb::StopShowColumn GetStopShowColumn() const
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)
bool SetScriptLanguage(lldb::ScriptLanguage script_lang)
bool LoadPlugin(const FileSpec &spec, Status &error)
void SetOutputFile(lldb::FileSP file)
uint64_t GetStopSourceLineCount(bool before) const
void EnableForwardEvents(const lldb::ListenerSP &listener_sp)
@ eBroadcastBitEventThreadIsListening
static lldb::DebuggerSP FindDebuggerWithID(lldb::user_id_t id)
void HandleBreakpointEvent(const lldb::EventSP &event_sp)
void JoinIOHandlerThread()
static ConstString GetStaticBroadcasterClass()
bool CheckTopIOHandlerTypes(IOHandler::Type top_type, IOHandler::Type second_top_type)
Target & GetDummyTarget()
const FormatEntity::Entry * GetFrameFormat() const
lldb::ListenerSP GetListener()
static void Destroy(lldb::DebuggerSP &debugger_sp)
SourceManager::SourceFileCache m_source_file_cache
std::optional< uint64_t > m_current_event_id
void RunIOHandlerSync(const lldb::IOHandlerSP &reader_sp)
Run the given IO handler and block until it's complete.
const FormatEntity::Entry * GetThreadFormat() const
Broadcaster & GetBroadcaster()
Get the public broadcaster for this debugger.
llvm::StringRef GetStopShowLineMarkerAnsiPrefix() const
uint64_t GetTabSize() const
lldb::StreamFileSP m_output_stream_sp
bool GetShowProgress() const
void HandleDestroyCallback()
std::mutex m_output_flush_mutex
llvm::StringRef GetStopShowLineMarkerAnsiSuffix() const
bool SetUseColor(bool use_color)
lldb_private::DebuggerDestroyCallback m_destroy_callback
const char * GetIOHandlerHelpPrologue()
Status SetInputString(const char *data)
bool GetUseAutosuggestion() const
Target & GetSelectedOrDummyTarget(bool prefer_dummy=false)
void HandleProcessEvent(const lldb::EventSP &event_sp)
IOHandlerStack m_io_handler_stack
repro::DataRecorder * m_input_recorder
Used for shadowing the input file when capturing a reproducer.
lldb::StreamFileSP GetOutputStreamSP()
llvm::once_flag m_clear_once
void AdoptTopIOHandlerFilesIfInvalid(lldb::FileSP &in, lldb::StreamFileSP &out, lldb::StreamFileSP &err)
static void SettingsTerminate()
lldb::LanguageType GetREPLLanguage() const
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)
Debugger(lldb::LogOutputCallback m_log_callback, void *baton)
llvm::StringRef GetExternalEditor() const
void HandleThreadEvent(const lldb::EventSP &event_sp)
static size_t GetNumDebuggers()
uint32_t m_interrupt_requested
Tracks interrupt requests.
lldb::DWIMPrintVerbosity GetDWIMPrintVerbosity() const
lldb::thread_result_t DefaultEventHandler()
void PrintAsync(const char *s, size_t len, bool is_stdout)
bool IsForwardingEvents()
llvm::StringRef GetPrompt() const
bool GetNotifyVoid() const
llvm::StringRef GetShowProgressAnsiPrefix() const
const FormatEntity::Entry * GetFrameFormatUnique() const
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.
bool SetAutoIndent(bool b)
llvm::StringRef GetStopShowColumnAnsiPrefix() const
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)
static lldb::ProcessSP GetProcessFromEvent(const Event *event_ptr)
static lldb::StructuredDataPluginSP GetPluginFromEvent(const Event *event_ptr)
static StructuredData::ObjectSP GetObjectFromEvent(const Event *event_ptr)
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.
FileSpec CopyByAppendingPathComponent(llvm::StringRef component) const
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
llvm::StringRef GetFileNameExtension() const
Extract the extension of the file.
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.
@ eEnumerateDirectoryResultNext
Enumerate next entry in the current directory.
@ eEnumerateDirectoryResultQuit
Stop directory enumerations at any level.
int Open(const char *path, int flags, int mode)
Wraps ::open in a platform-independent way.
static FileSystem & Instance()
An abstract base class for files.
static int kInvalidDescriptor
virtual int GetDescriptor() const
Get underlying OS file descriptor for this file, or kInvalidDescriptor.
bool GetIsTerminalWithColors()
Return true if this file is a terminal which supports colors.
Status Close() override
Flush any buffers and release any resources owned by the file.
bool GetIsInteractive()
Return true if this file is interactive.
const Mangled & GetMangled() const
Status Join(lldb::thread_result_t *result)
bool EqualsThread(lldb::thread_t thread) const
static lldb::thread_t GetCurrentThread()
Get the thread token (the one returned by ThreadCreate when the thread was created) for the calling t...
const char * GetTopIOHandlerHelpPrologue()
bool PrintAsync(const char *s, size_t len, bool is_stdout)
ConstString GetTopIOHandlerControlSequence(char ch)
bool IsTop(const lldb::IOHandlerSP &io_handler_sp) const
void Push(const lldb::IOHandlerSP &sp)
std::recursive_mutex & GetMutex()
bool CheckTopIOHandlerTypes(IOHandler::Type top_type, IOHandler::Type second_top_type)
const char * GetTopIOHandlerCommandPrefix()
static LanguageSet GetLanguagesSupportingREPLs()
static const char * GetNameForLanguageType(lldb::LanguageType language)
static lldb::ListenerSP MakeListener(const char *name)
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)
void PutString(llvm::StringRef str)
static ModuleListProperties & GetGlobalModuleListProperties()
void SetMaximumValue(int64_t v)
void SetMinimumValue(int64_t v)
static lldb::ScriptInterpreterSP GetScriptInterpreterForLanguage(lldb::ScriptLanguage script_lang, Debugger &debugger)
static void DebuggerInitialize(Debugger &debugger)
static lldb::ProcessSP GetProcessFromEvent(const Event *event_ptr)
static lldb::StateType GetStateFromEvent(const Event *event_ptr)
A plug-in interface definition class for debugging a process.
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.
@ eBroadcastBitStructuredData
@ eBroadcastBitStateChanged
virtual size_t GetSTDERR(char *buf, size_t buf_size, Status &error)
Get any available STDERR.
static ConstString & GetStaticBroadcasterClass()
virtual size_t GetSTDOUT(char *buf, size_t buf_size, Status &error)
Get any available STDOUT.
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)
bool SetPropertyAtIndex(uint32_t idx, T t, const ExecutionContext *exe_ctx=nullptr) const
virtual 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...
int SetErrorStringWithFormat(const char *format,...) __attribute__((format(printf
Set the current error string to a formatted error string.
void SetErrorString(llvm::StringRef err_str)
Set the current error string to err_str.
bool Success() const
Test for success condition.
void Flush() override
Flush the stream.
llvm::StringRef GetString() const
A stream class that can stream formatted output to a file.
size_t Write(const void *src, size_t src_len)
Output character bytes to the stream.
llvm::raw_ostream & AsRawOstream()
Returns a raw_ostream that forwards the data to this Stream object.
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
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
ConstString GetName() const
lldb::SymbolType GetType() const
lldb::TargetSP GetSelectedTarget()
static ConstString & GetStaticBroadcasterClass()
static void SettingsTerminate()
@ eBroadcastBitBreakpointChanged
static TargetProperties & GetGlobalProperties()
static ArchSpec GetDefaultArchitecture()
static void SettingsInitialize()
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)
static ConstString & GetStaticBroadcasterClass()
@ eBroadcastBitThreadSelected
@ eBroadcastBitStackChanged
@ SelectMostRelevantFrame
#define LLDB_INVALID_HOST_THREAD
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.
@ eLoadScriptFromSymFileTrue
@ eLoadScriptFromSymFileFalse
@ eLoadScriptFromSymFileWarn
bool StateIsStoppedState(lldb::StateType state, bool must_exist)
Check if a state represents a state where the process or thread is stopped.
VarSetOperationType
Settable state variable types.
ScriptLanguage
Script interpreter types.
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.
@ eStopShowColumnAnsiOrCaret
void(* LogOutputCallback)(const char *, void *baton)
A SmallBitVector that represents a set of source languages (lldb::LanguageType).
std::optional< lldb::LanguageType > GetSingularLanguage()
If the set contains a single language only, return it.
A mix in class that contains a generic user ID.
lldb::user_id_t GetID() const
Get accessor for the user ID.