Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:42:44

0001 //===-- Debugger.h ----------------------------------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
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 } // namespace llvm
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 /// \class Debugger Debugger.h "lldb/Core/Debugger.h"
0074 /// A class to manage flag bits.
0075 ///
0076 /// Provides a global root objects for the debugger core.
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   /// Get the public broadcaster for this debugger.
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   // This returns the Debugger's scratch source manager.  It won't be able to
0180   // look up files in debug information, but it can look up files by absolute
0181   // path and display them to you. To get the target's source manager, call
0182   // GetSourceManager on the target instead.
0183   SourceManager &GetSourceManager();
0184 
0185   lldb::TargetSP GetSelectedTarget() {
0186     return m_target_list.GetSelectedTarget();
0187   }
0188 
0189   ExecutionContext GetSelectedExecutionContext();
0190   /// Get accessor for the target list.
0191   ///
0192   /// The target list is part of the global debugger object. This the single
0193   /// debugger shared instance to control where targets get created and to
0194   /// allow for tracking and searching for targets based on certain criteria.
0195   ///
0196   /// \return
0197   ///     A global shared target list.
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   // If any of the streams are not set, set them to the in/out/err stream of
0207   // the top most input reader to ensure they at least have something
0208   void AdoptTopIOHandlerFilesIfInvalid(lldb::FileSP &in,
0209                                        lldb::StreamFileSP &out,
0210                                        lldb::StreamFileSP &err);
0211 
0212   /// Run the given IO handler and return immediately.
0213   void RunIOHandlerAsync(const lldb::IOHandlerSP &reader_sp,
0214                          bool cancel_top_handler = true);
0215 
0216   /// Run the given IO handler and block until it's complete.
0217   void RunIOHandlerSync(const lldb::IOHandlerSP &reader_sp);
0218 
0219   ///  Remove the given IO handler if it's currently active.
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   // Properties Functions
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   /// Interruption in LLDB:
0390   ///
0391   /// This is a voluntary interruption mechanism, not preemptive.  Parts of lldb
0392   /// that do work that can be safely interrupted call
0393   /// Debugger::InterruptRequested and if that returns true, they should return
0394   /// at a safe point, shortcutting the rest of the work they were to do.
0395   ///
0396   /// lldb clients can both offer a CommandInterpreter (through
0397   /// RunCommandInterpreter) and use the SB API's for their own purposes, so it
0398   /// is convenient to separate "interrupting the CommandInterpreter execution"
0399   /// and interrupting the work it is doing with the SB API's.  So there are two
0400   /// ways to cause an interrupt:
0401   ///   * CommandInterpreter::InterruptCommand: Interrupts the command currently
0402   ///     running in the command interpreter IOHandler thread
0403   ///   * Debugger::RequestInterrupt: Interrupts are active on anything but the
0404   ///     CommandInterpreter thread till CancelInterruptRequest is called.
0405   ///
0406   /// Since the two checks are mutually exclusive, however, it's also convenient
0407   /// to have just one function to check the interrupt state.
0408 
0409   /// Bump the "interrupt requested" count on the debugger to support
0410   /// cooperative interruption.  If this is non-zero, InterruptRequested will
0411   /// return true.  Interruptible operations are expected to query the
0412   /// InterruptRequested API periodically, and interrupt what they were doing
0413   /// if it returns \b true.
0414   ///
0415   void RequestInterrupt();
0416 
0417   /// Decrement the "interrupt requested" counter.
0418   void CancelInterruptRequest();
0419 
0420   /// This is the correct way to query the state of Interruption.
0421   /// If you are on the RunCommandInterpreter thread, it will check the
0422   /// command interpreter state, and if it is on another thread it will
0423   /// check the debugger Interrupt Request state.
0424   /// \param[in] cur_func
0425   /// For reporting if the interruption was requested.  Don't provide this by
0426   /// hand, use INTERRUPT_REQUESTED so this gets done consistently.
0427   ///
0428   /// \param[in] formatv
0429   /// A formatv string for the interrupt message.  If the elements of the
0430   /// message are expensive to compute, you can use the no-argument form of
0431   /// InterruptRequested, then make up the report using REPORT_INTERRUPTION.
0432   ///
0433   /// \return
0434   ///  A boolean value, if \b true an interruptible operation should interrupt
0435   ///  itself.
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   /// This handy define will keep you from having to generate a report for the
0452   /// interruption by hand.  Use this except in the case where the arguments to
0453   /// the message description are expensive to compute.
0454 #define INTERRUPT_REQUESTED(debugger, ...)                                     \
0455   (debugger).InterruptRequested(__func__, __VA_ARGS__)
0456 
0457   // This form just queries for whether to interrupt, and does no reporting:
0458   bool InterruptRequested();
0459 
0460   // FIXME: Do we want to capture a backtrace at the interruption point?
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   // This is for use in the command interpreter, when you either want the
0493   // selected target, or if no target is present you want to prime the dummy
0494   // target with entities that will be copied over to new targets.
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   /// Shared thread pool. Use only with ThreadPoolTaskGroup.
0503   static llvm::ThreadPoolInterface &GetThreadPool();
0504 
0505   /// Report warning events.
0506   ///
0507   /// Warning events will be delivered to any debuggers that have listeners
0508   /// for the eBroadcastBitWarning.
0509   ///
0510   /// \param[in] message
0511   ///   The warning message to be reported.
0512   ///
0513   /// \param [in] debugger_id
0514   ///   If this optional parameter has a value, it indicates the unique
0515   ///   debugger identifier that this diagnostic should be delivered to. If
0516   ///   this optional parameter does not have a value, the diagnostic event
0517   ///   will be delivered to all debuggers.
0518   ///
0519   /// \param [in] once
0520   ///   If a pointer is passed to a std::once_flag, then it will be used to
0521   ///   ensure the given warning is only broadcast once.
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   /// Report error events.
0528   ///
0529   /// Error events will be delivered to any debuggers that have listeners
0530   /// for the eBroadcastBitError.
0531   ///
0532   /// \param[in] message
0533   ///   The error message to be reported.
0534   ///
0535   /// \param [in] debugger_id
0536   ///   If this optional parameter has a value, it indicates the unique
0537   ///   debugger identifier that this diagnostic should be delivered to. If
0538   ///   this optional parameter does not have a value, the diagnostic event
0539   ///   will be delivered to all debuggers.
0540   ///
0541   /// \param [in] once
0542   ///   If a pointer is passed to a std::once_flag, then it will be used to
0543   ///   ensure the given error is only broadcast once.
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   /// Report info events.
0550   ///
0551   /// Unlike warning and error events, info events are not broadcast but are
0552   /// logged for diagnostic purposes.
0553   ///
0554   /// \param[in] message
0555   ///   The info message to be reported.
0556   ///
0557   /// \param [in] debugger_id
0558   ///   If this optional parameter has a value, it indicates this diagnostic is
0559   ///   associated with a unique debugger instance.
0560   ///
0561   /// \param [in] once
0562   ///   If a pointer is passed to a std::once_flag, then it will be used to
0563   ///   ensure the given info is only logged once.
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   /// DEPRECATED: We used to only support one Destroy callback. Now that we
0572   /// support Add and Remove, you should only remove callbacks that you added.
0573   /// Use Add and Remove instead.
0574   ///
0575   /// Clear all previously added callbacks and only add the given one.
0576   void
0577   SetDestroyCallback(lldb_private::DebuggerDestroyCallback destroy_callback,
0578                      void *baton);
0579 
0580   /// Add a callback for when the debugger is destroyed. Return a token, which
0581   /// can be used to remove said callback. Multiple callbacks can be added by
0582   /// calling this function multiple times, and will be invoked in FIFO order.
0583   lldb::callback_token_t
0584   AddDestroyCallback(lldb_private::DebuggerDestroyCallback destroy_callback,
0585                      void *baton);
0586 
0587   /// Remove the specified callback. Return true if successful.
0588   bool RemoveDestroyCallback(lldb::callback_token_t token);
0589 
0590   /// Manually start the global event handler thread. It is useful to plugins
0591   /// that directly use the \a lldb_private namespace and want to use the
0592   /// debugger's default event handler thread instead of defining their own.
0593   bool StartEventHandlerThread();
0594 
0595   /// Manually stop the debugger's default event handler.
0596   void StopEventHandlerThread();
0597 
0598   /// Force flushing the process's pending stdout and stderr to the debugger's
0599   /// asynchronous stdout and stderr streams.
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   /// Report progress events.
0614   ///
0615   /// Progress events will be delivered to any debuggers that have listeners
0616   /// for the eBroadcastBitProgress. This function is called by the
0617   /// lldb_private::Progress class to deliver the events to any debuggers that
0618   /// qualify.
0619   ///
0620   /// \param [in] progress_id
0621   ///   The unique integer identifier for the progress to report.
0622   ///
0623   /// \param[in] message
0624   ///   The title of the progress dialog to display in the UI.
0625   ///
0626   /// \param [in] completed
0627   ///   The amount of work completed. If \a completed is zero, then this event
0628   ///   is a progress started event. If \a completed is equal to \a total, then
0629   ///   this event is a progress end event. Otherwise completed indicates the
0630   ///   current progress compare to the total value.
0631   ///
0632   /// \param [in] total
0633   ///   The total amount of work units that need to be completed. If this value
0634   ///   is UINT64_MAX, then an indeterminate progress indicator should be
0635   ///   displayed.
0636   ///
0637   /// \param [in] debugger_id
0638   ///   If this optional parameter has a value, it indicates the unique
0639   ///   debugger identifier that this progress should be delivered to. If this
0640   ///   optional parameter does not have a value, the progress will be
0641   ///   delivered to all debuggers.
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   // Sets the IOHandler thread to the new_thread, and returns
0668   // the previous IOHandler thread.
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   // Ensures two threads don't attempt to flush process output in parallel.
0690   std::mutex m_output_flush_mutex;
0691 
0692   void InstanceInitialize();
0693 
0694   // these should never be NULL
0695   lldb::FileSP m_input_file_sp;
0696   lldb::StreamFileSP m_output_stream_sp;
0697   lldb::StreamFileSP m_error_stream_sp;
0698 
0699   /// Used for shadowing the input file when capturing a reproducer.
0700   repro::DataRecorder *m_input_recorder;
0701 
0702   lldb::BroadcasterManagerSP m_broadcaster_manager_sp; // The debugger acts as a
0703                                                        // broadcaster manager of
0704                                                        // last resort.
0705   // It needs to get constructed before the target_list or any other member
0706   // that might want to broadcast through the debugger.
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; // This is a scratch
0714                                                       // source manager that we
0715                                                       // return if we have no
0716                                                       // targets.
0717   SourceManager::SourceFileCache m_source_file_cache; // All the source managers
0718                                                       // for targets created in
0719                                                       // this debugger used this
0720                                                       // shared
0721                                                       // source file cache.
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; ///< Private debugger synchronization.
0742   Broadcaster m_broadcaster;      ///< Public Debugger event 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; ///< Tracks interrupt requests
0763   std::mutex m_interrupt_mutex;
0764 
0765   // Events for m_sync_broadcaster
0766   enum {
0767     eBroadcastBitEventThreadIsListening = (1 << 0),
0768   };
0769 
0770 private:
0771   // Use Debugger::CreateInstance() to get a shared pointer to a new debugger
0772   // object
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 } // namespace lldb_private
0780 
0781 #endif // LLDB_CORE_DEBUGGER_H