File indexing completed on 2026-05-10 08:42:44
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef LLDB_CORE_DEBUGGER_H
0010 #define LLDB_CORE_DEBUGGER_H
0011
0012 #include <cstdint>
0013
0014 #include <memory>
0015 #include <optional>
0016 #include <vector>
0017
0018 #include "lldb/Core/DebuggerEvents.h"
0019 #include "lldb/Core/FormatEntity.h"
0020 #include "lldb/Core/IOHandler.h"
0021 #include "lldb/Core/SourceManager.h"
0022 #include "lldb/Core/UserSettingsController.h"
0023 #include "lldb/Host/HostThread.h"
0024 #include "lldb/Host/StreamFile.h"
0025 #include "lldb/Host/Terminal.h"
0026 #include "lldb/Target/ExecutionContext.h"
0027 #include "lldb/Target/Platform.h"
0028 #include "lldb/Target/TargetList.h"
0029 #include "lldb/Utility/Broadcaster.h"
0030 #include "lldb/Utility/ConstString.h"
0031 #include "lldb/Utility/Diagnostics.h"
0032 #include "lldb/Utility/FileSpec.h"
0033 #include "lldb/Utility/Status.h"
0034 #include "lldb/Utility/UserID.h"
0035 #include "lldb/lldb-defines.h"
0036 #include "lldb/lldb-enumerations.h"
0037 #include "lldb/lldb-forward.h"
0038 #include "lldb/lldb-private-enumerations.h"
0039 #include "lldb/lldb-private-types.h"
0040 #include "lldb/lldb-types.h"
0041
0042 #include "llvm/ADT/ArrayRef.h"
0043 #include "llvm/ADT/SmallVector.h"
0044 #include "llvm/ADT/StringMap.h"
0045 #include "llvm/ADT/StringRef.h"
0046 #include "llvm/Support/DynamicLibrary.h"
0047 #include "llvm/Support/FormatVariadic.h"
0048 #include "llvm/Support/Threading.h"
0049
0050 #include <cassert>
0051 #include <cstddef>
0052 #include <cstdio>
0053
0054 namespace llvm {
0055 class raw_ostream;
0056 class ThreadPoolInterface;
0057 }
0058
0059 namespace lldb_private {
0060 class Address;
0061 class CallbackLogHandler;
0062 class CommandInterpreter;
0063 class LogHandler;
0064 class Process;
0065 class Stream;
0066 class SymbolContext;
0067 class Target;
0068
0069 namespace repro {
0070 class DataRecorder;
0071 }
0072
0073
0074
0075
0076
0077
0078 class Debugger : public std::enable_shared_from_this<Debugger>,
0079 public UserID,
0080 public Properties {
0081 public:
0082 using DebuggerList = std::vector<lldb::DebuggerSP>;
0083
0084 static llvm::StringRef GetStaticBroadcasterClass();
0085
0086
0087 Broadcaster &GetBroadcaster() { return m_broadcaster; }
0088 const Broadcaster &GetBroadcaster() const { return m_broadcaster; }
0089
0090 ~Debugger() override;
0091
0092 static lldb::DebuggerSP
0093 CreateInstance(lldb::LogOutputCallback log_callback = nullptr,
0094 void *baton = nullptr);
0095
0096 static lldb::TargetSP FindTargetWithProcessID(lldb::pid_t pid);
0097
0098 static lldb::TargetSP FindTargetWithProcess(Process *process);
0099
0100 static void Initialize(LoadPluginCallbackType load_plugin_callback);
0101
0102 static void Terminate();
0103
0104 static void SettingsInitialize();
0105
0106 static void SettingsTerminate();
0107
0108 static void Destroy(lldb::DebuggerSP &debugger_sp);
0109
0110 static lldb::DebuggerSP FindDebuggerWithID(lldb::user_id_t id);
0111
0112 static lldb::DebuggerSP
0113 FindDebuggerWithInstanceName(llvm::StringRef instance_name);
0114
0115 static size_t GetNumDebuggers();
0116
0117 static lldb::DebuggerSP GetDebuggerAtIndex(size_t index);
0118
0119 static bool FormatDisassemblerAddress(const FormatEntity::Entry *format,
0120 const SymbolContext *sc,
0121 const SymbolContext *prev_sc,
0122 const ExecutionContext *exe_ctx,
0123 const Address *addr, Stream &s);
0124
0125 static void AssertCallback(llvm::StringRef message, llvm::StringRef backtrace,
0126 llvm::StringRef prompt);
0127
0128 void Clear();
0129
0130 bool GetAsyncExecution();
0131
0132 void SetAsyncExecution(bool async);
0133
0134 lldb::FileSP GetInputFileSP() { return m_input_file_sp; }
0135
0136 lldb::StreamFileSP GetOutputStreamSP() { return m_output_stream_sp; }
0137
0138 lldb::StreamFileSP GetErrorStreamSP() { return m_error_stream_sp; }
0139
0140 File &GetInputFile() { return *m_input_file_sp; }
0141
0142 File &GetOutputFile() { return m_output_stream_sp->GetFile(); }
0143
0144 File &GetErrorFile() { return m_error_stream_sp->GetFile(); }
0145
0146 StreamFile &GetOutputStream() { return *m_output_stream_sp; }
0147
0148 StreamFile &GetErrorStream() { return *m_error_stream_sp; }
0149
0150 repro::DataRecorder *GetInputRecorder();
0151
0152 Status SetInputString(const char *data);
0153
0154 void SetInputFile(lldb::FileSP file);
0155
0156 void SetOutputFile(lldb::FileSP file);
0157
0158 void SetErrorFile(lldb::FileSP file);
0159
0160 void SaveInputTerminalState();
0161
0162 void RestoreInputTerminalState();
0163
0164 lldb::StreamSP GetAsyncOutputStream();
0165
0166 lldb::StreamSP GetAsyncErrorStream();
0167
0168 CommandInterpreter &GetCommandInterpreter() {
0169 assert(m_command_interpreter_up.get());
0170 return *m_command_interpreter_up;
0171 }
0172
0173 ScriptInterpreter *
0174 GetScriptInterpreter(bool can_create = true,
0175 std::optional<lldb::ScriptLanguage> language = {});
0176
0177 lldb::ListenerSP GetListener() { return m_listener_sp; }
0178
0179
0180
0181
0182
0183 SourceManager &GetSourceManager();
0184
0185 lldb::TargetSP GetSelectedTarget() {
0186 return m_target_list.GetSelectedTarget();
0187 }
0188
0189 ExecutionContext GetSelectedExecutionContext();
0190
0191
0192
0193
0194
0195
0196
0197
0198 TargetList &GetTargetList() { return m_target_list; }
0199
0200 PlatformList &GetPlatformList() { return m_platform_list; }
0201
0202 void DispatchInputInterrupt();
0203
0204 void DispatchInputEndOfFile();
0205
0206
0207
0208 void AdoptTopIOHandlerFilesIfInvalid(lldb::FileSP &in,
0209 lldb::StreamFileSP &out,
0210 lldb::StreamFileSP &err);
0211
0212
0213 void RunIOHandlerAsync(const lldb::IOHandlerSP &reader_sp,
0214 bool cancel_top_handler = true);
0215
0216
0217 void RunIOHandlerSync(const lldb::IOHandlerSP &reader_sp);
0218
0219
0220 bool RemoveIOHandler(const lldb::IOHandlerSP &reader_sp);
0221
0222 bool IsTopIOHandler(const lldb::IOHandlerSP &reader_sp);
0223
0224 bool CheckTopIOHandlerTypes(IOHandler::Type top_type,
0225 IOHandler::Type second_top_type);
0226
0227 void PrintAsync(const char *s, size_t len, bool is_stdout);
0228
0229 llvm::StringRef GetTopIOHandlerControlSequence(char ch);
0230
0231 const char *GetIOHandlerCommandPrefix();
0232
0233 const char *GetIOHandlerHelpPrologue();
0234
0235 void ClearIOHandlers();
0236
0237 bool EnableLog(llvm::StringRef channel,
0238 llvm::ArrayRef<const char *> categories,
0239 llvm::StringRef log_file, uint32_t log_options,
0240 size_t buffer_size, LogHandlerKind log_handler_kind,
0241 llvm::raw_ostream &error_stream);
0242
0243 void SetLoggingCallback(lldb::LogOutputCallback log_callback, void *baton);
0244
0245
0246 enum StopDisassemblyType {
0247 eStopDisassemblyTypeNever = 0,
0248 eStopDisassemblyTypeNoDebugInfo,
0249 eStopDisassemblyTypeNoSource,
0250 eStopDisassemblyTypeAlways
0251 };
0252
0253 Status SetPropertyValue(const ExecutionContext *exe_ctx,
0254 VarSetOperationType op, llvm::StringRef property_path,
0255 llvm::StringRef value) override;
0256
0257 bool GetAutoConfirm() const;
0258
0259 const FormatEntity::Entry *GetDisassemblyFormat() const;
0260
0261 const FormatEntity::Entry *GetFrameFormat() const;
0262
0263 const FormatEntity::Entry *GetFrameFormatUnique() const;
0264
0265 uint64_t GetStopDisassemblyMaxSize() const;
0266
0267 const FormatEntity::Entry *GetThreadFormat() const;
0268
0269 const FormatEntity::Entry *GetThreadStopFormat() const;
0270
0271 lldb::ScriptLanguage GetScriptLanguage() const;
0272
0273 bool SetScriptLanguage(lldb::ScriptLanguage script_lang);
0274
0275 lldb::LanguageType GetREPLLanguage() const;
0276
0277 bool SetREPLLanguage(lldb::LanguageType repl_lang);
0278
0279 uint64_t GetTerminalWidth() const;
0280
0281 bool SetTerminalWidth(uint64_t term_width);
0282
0283 uint64_t GetTerminalHeight() const;
0284
0285 bool SetTerminalHeight(uint64_t term_height);
0286
0287 llvm::StringRef GetPrompt() const;
0288
0289 llvm::StringRef GetPromptAnsiPrefix() const;
0290
0291 llvm::StringRef GetPromptAnsiSuffix() const;
0292
0293 void SetPrompt(llvm::StringRef p);
0294 void SetPrompt(const char *) = delete;
0295
0296 bool GetUseExternalEditor() const;
0297 bool SetUseExternalEditor(bool use_external_editor_p);
0298
0299 llvm::StringRef GetExternalEditor() const;
0300
0301 bool SetExternalEditor(llvm::StringRef editor);
0302
0303 bool GetUseColor() const;
0304
0305 bool SetUseColor(bool use_color);
0306
0307 bool GetShowProgress() const;
0308
0309 bool SetShowProgress(bool show_progress);
0310
0311 llvm::StringRef GetShowProgressAnsiPrefix() const;
0312
0313 llvm::StringRef GetShowProgressAnsiSuffix() const;
0314
0315 bool GetUseAutosuggestion() const;
0316
0317 llvm::StringRef GetAutosuggestionAnsiPrefix() const;
0318
0319 llvm::StringRef GetAutosuggestionAnsiSuffix() const;
0320
0321 llvm::StringRef GetRegexMatchAnsiPrefix() const;
0322
0323 llvm::StringRef GetRegexMatchAnsiSuffix() const;
0324
0325 bool GetShowDontUsePoHint() const;
0326
0327 bool GetUseSourceCache() const;
0328
0329 bool SetUseSourceCache(bool use_source_cache);
0330
0331 bool GetHighlightSource() const;
0332
0333 lldb::StopShowColumn GetStopShowColumn() const;
0334
0335 llvm::StringRef GetStopShowColumnAnsiPrefix() const;
0336
0337 llvm::StringRef GetStopShowColumnAnsiSuffix() const;
0338
0339 uint64_t GetStopSourceLineCount(bool before) const;
0340
0341 StopDisassemblyType GetStopDisassemblyDisplay() const;
0342
0343 uint64_t GetDisassemblyLineCount() const;
0344
0345 llvm::StringRef GetStopShowLineMarkerAnsiPrefix() const;
0346
0347 llvm::StringRef GetStopShowLineMarkerAnsiSuffix() const;
0348
0349 bool GetAutoOneLineSummaries() const;
0350
0351 bool GetAutoIndent() const;
0352
0353 bool SetAutoIndent(bool b);
0354
0355 bool GetPrintDecls() const;
0356
0357 bool SetPrintDecls(bool b);
0358
0359 uint64_t GetTabSize() const;
0360
0361 bool SetTabSize(uint64_t tab_size);
0362
0363 lldb::DWIMPrintVerbosity GetDWIMPrintVerbosity() const;
0364
0365 bool GetEscapeNonPrintables() const;
0366
0367 bool GetNotifyVoid() const;
0368
0369 const std::string &GetInstanceName() { return m_instance_name; }
0370
0371 bool GetShowInlineDiagnostics() const;
0372
0373 bool SetShowInlineDiagnostics(bool);
0374
0375 bool LoadPlugin(const FileSpec &spec, Status &error);
0376
0377 void RunIOHandlers();
0378
0379 bool IsForwardingEvents();
0380
0381 void EnableForwardEvents(const lldb::ListenerSP &listener_sp);
0382
0383 void CancelForwardEvents(const lldb::ListenerSP &listener_sp);
0384
0385 bool IsHandlingEvents() const { return m_event_handler_thread.IsJoinable(); }
0386
0387 Status RunREPL(lldb::LanguageType language, const char *repl_options);
0388
0389
0390
0391
0392
0393
0394
0395
0396
0397
0398
0399
0400
0401
0402
0403
0404
0405
0406
0407
0408
0409
0410
0411
0412
0413
0414
0415 void RequestInterrupt();
0416
0417
0418 void CancelInterruptRequest();
0419
0420
0421
0422
0423
0424
0425
0426
0427
0428
0429
0430
0431
0432
0433
0434
0435
0436 template <typename... Args>
0437 bool InterruptRequested(const char *cur_func, const char *formatv,
0438 Args &&...args) {
0439 bool ret_val = InterruptRequested();
0440 if (ret_val) {
0441 if (!formatv)
0442 formatv = "Unknown message";
0443 if (!cur_func)
0444 cur_func = "<UNKNOWN>";
0445 ReportInterruption(InterruptionReport(
0446 cur_func, llvm::formatv(formatv, std::forward<Args>(args)...)));
0447 }
0448 return ret_val;
0449 }
0450
0451
0452
0453
0454 #define INTERRUPT_REQUESTED(debugger, ...) \
0455 (debugger).InterruptRequested(__func__, __VA_ARGS__)
0456
0457
0458 bool InterruptRequested();
0459
0460
0461 class InterruptionReport {
0462 public:
0463 InterruptionReport(std::string function_name, std::string description)
0464 : m_function_name(std::move(function_name)),
0465 m_description(std::move(description)),
0466 m_interrupt_time(std::chrono::system_clock::now()),
0467 m_thread_id(llvm::get_threadid()) {}
0468
0469 InterruptionReport(std::string function_name,
0470 const llvm::formatv_object_base &payload);
0471
0472 template <typename... Args>
0473 InterruptionReport(std::string function_name, const char *format,
0474 Args &&...args)
0475 : InterruptionReport(
0476 function_name,
0477 llvm::formatv(format, std::forward<Args>(args)...)) {}
0478
0479 std::string m_function_name;
0480 std::string m_description;
0481 const std::chrono::time_point<std::chrono::system_clock> m_interrupt_time;
0482 const uint64_t m_thread_id;
0483 };
0484 void ReportInterruption(const InterruptionReport &report);
0485 #define REPORT_INTERRUPTION(debugger, ...) \
0486 (debugger).ReportInterruption( \
0487 Debugger::InterruptionReport(__func__, __VA_ARGS__))
0488
0489 static DebuggerList DebuggersRequestingInterruption();
0490
0491 public:
0492
0493
0494
0495 Target &GetSelectedOrDummyTarget(bool prefer_dummy = false);
0496 Target &GetDummyTarget() { return *m_dummy_target_sp; }
0497
0498 lldb::BroadcasterManagerSP GetBroadcasterManager() {
0499 return m_broadcaster_manager_sp;
0500 }
0501
0502
0503 static llvm::ThreadPoolInterface &GetThreadPool();
0504
0505
0506
0507
0508
0509
0510
0511
0512
0513
0514
0515
0516
0517
0518
0519
0520
0521
0522 static void
0523 ReportWarning(std::string message,
0524 std::optional<lldb::user_id_t> debugger_id = std::nullopt,
0525 std::once_flag *once = nullptr);
0526
0527
0528
0529
0530
0531
0532
0533
0534
0535
0536
0537
0538
0539
0540
0541
0542
0543
0544 static void
0545 ReportError(std::string message,
0546 std::optional<lldb::user_id_t> debugger_id = std::nullopt,
0547 std::once_flag *once = nullptr);
0548
0549
0550
0551
0552
0553
0554
0555
0556
0557
0558
0559
0560
0561
0562
0563
0564 static void
0565 ReportInfo(std::string message,
0566 std::optional<lldb::user_id_t> debugger_id = std::nullopt,
0567 std::once_flag *once = nullptr);
0568
0569 static void ReportSymbolChange(const ModuleSpec &module_spec);
0570
0571
0572
0573
0574
0575
0576 void
0577 SetDestroyCallback(lldb_private::DebuggerDestroyCallback destroy_callback,
0578 void *baton);
0579
0580
0581
0582
0583 lldb::callback_token_t
0584 AddDestroyCallback(lldb_private::DebuggerDestroyCallback destroy_callback,
0585 void *baton);
0586
0587
0588 bool RemoveDestroyCallback(lldb::callback_token_t token);
0589
0590
0591
0592
0593 bool StartEventHandlerThread();
0594
0595
0596 void StopEventHandlerThread();
0597
0598
0599
0600 void FlushProcessOutput(Process &process, bool flush_stdout,
0601 bool flush_stderr);
0602
0603 SourceManager::SourceFileCache &GetSourceFileCache() {
0604 return m_source_file_cache;
0605 }
0606
0607 protected:
0608 friend class CommandInterpreter;
0609 friend class REPL;
0610 friend class Progress;
0611 friend class ProgressManager;
0612
0613
0614
0615
0616
0617
0618
0619
0620
0621
0622
0623
0624
0625
0626
0627
0628
0629
0630
0631
0632
0633
0634
0635
0636
0637
0638
0639
0640
0641
0642 static void
0643 ReportProgress(uint64_t progress_id, std::string title, std::string details,
0644 uint64_t completed, uint64_t total,
0645 std::optional<lldb::user_id_t> debugger_id,
0646 uint32_t progress_category_bit = lldb::eBroadcastBitProgress);
0647
0648 static void ReportDiagnosticImpl(lldb::Severity severity, std::string message,
0649 std::optional<lldb::user_id_t> debugger_id,
0650 std::once_flag *once);
0651
0652 void HandleDestroyCallback();
0653
0654 void PrintProgress(const ProgressEventData &data);
0655
0656 void PushIOHandler(const lldb::IOHandlerSP &reader_sp,
0657 bool cancel_top_handler = true);
0658
0659 bool PopIOHandler(const lldb::IOHandlerSP &reader_sp);
0660
0661 bool HasIOHandlerThread() const;
0662
0663 bool StartIOHandlerThread();
0664
0665 void StopIOHandlerThread();
0666
0667
0668
0669 HostThread SetIOHandlerThread(HostThread &new_thread);
0670
0671 void JoinIOHandlerThread();
0672
0673 bool IsIOHandlerThreadCurrentThread() const;
0674
0675 lldb::thread_result_t IOHandlerThread();
0676
0677 lldb::thread_result_t DefaultEventHandler();
0678
0679 void HandleBreakpointEvent(const lldb::EventSP &event_sp);
0680
0681 void HandleProcessEvent(const lldb::EventSP &event_sp);
0682
0683 void HandleThreadEvent(const lldb::EventSP &event_sp);
0684
0685 void HandleProgressEvent(const lldb::EventSP &event_sp);
0686
0687 void HandleDiagnosticEvent(const lldb::EventSP &event_sp);
0688
0689
0690 std::mutex m_output_flush_mutex;
0691
0692 void InstanceInitialize();
0693
0694
0695 lldb::FileSP m_input_file_sp;
0696 lldb::StreamFileSP m_output_stream_sp;
0697 lldb::StreamFileSP m_error_stream_sp;
0698
0699
0700 repro::DataRecorder *m_input_recorder;
0701
0702 lldb::BroadcasterManagerSP m_broadcaster_manager_sp;
0703
0704
0705
0706
0707
0708 TerminalState m_terminal_state;
0709 TargetList m_target_list;
0710
0711 PlatformList m_platform_list;
0712 lldb::ListenerSP m_listener_sp;
0713 std::unique_ptr<SourceManager> m_source_manager_up;
0714
0715
0716
0717 SourceManager::SourceFileCache m_source_file_cache;
0718
0719
0720
0721
0722 std::unique_ptr<CommandInterpreter> m_command_interpreter_up;
0723
0724 std::recursive_mutex m_script_interpreter_mutex;
0725 std::array<lldb::ScriptInterpreterSP, lldb::eScriptLanguageUnknown>
0726 m_script_interpreters;
0727
0728 IOHandlerStack m_io_handler_stack;
0729 std::recursive_mutex m_io_handler_synchronous_mutex;
0730
0731 std::optional<uint64_t> m_current_event_id;
0732
0733 llvm::StringMap<std::weak_ptr<LogHandler>> m_stream_handlers;
0734 std::shared_ptr<CallbackLogHandler> m_callback_handler_sp;
0735 const std::string m_instance_name;
0736 static LoadPluginCallbackType g_load_plugin_callback;
0737 typedef std::vector<llvm::sys::DynamicLibrary> LoadedPluginsList;
0738 LoadedPluginsList m_loaded_plugins;
0739 HostThread m_event_handler_thread;
0740 HostThread m_io_handler_thread;
0741 Broadcaster m_sync_broadcaster;
0742 Broadcaster m_broadcaster;
0743 lldb::ListenerSP m_forward_listener_sp;
0744 llvm::once_flag m_clear_once;
0745 lldb::TargetSP m_dummy_target_sp;
0746 Diagnostics::CallbackID m_diagnostics_callback_id;
0747
0748 std::mutex m_destroy_callback_mutex;
0749 lldb::callback_token_t m_destroy_callback_next_token = 0;
0750 struct DestroyCallbackInfo {
0751 DestroyCallbackInfo() {}
0752 DestroyCallbackInfo(lldb::callback_token_t token,
0753 lldb_private::DebuggerDestroyCallback callback,
0754 void *baton)
0755 : token(token), callback(callback), baton(baton) {}
0756 lldb::callback_token_t token;
0757 lldb_private::DebuggerDestroyCallback callback;
0758 void *baton;
0759 };
0760 llvm::SmallVector<DestroyCallbackInfo, 2> m_destroy_callbacks;
0761
0762 uint32_t m_interrupt_requested = 0;
0763 std::mutex m_interrupt_mutex;
0764
0765
0766 enum {
0767 eBroadcastBitEventThreadIsListening = (1 << 0),
0768 };
0769
0770 private:
0771
0772
0773 Debugger(lldb::LogOutputCallback m_log_callback, void *baton);
0774
0775 Debugger(const Debugger &) = delete;
0776 const Debugger &operator=(const Debugger &) = delete;
0777 };
0778
0779 }
0780
0781 #endif