xref: /freebsd/contrib/llvm-project/lldb/include/lldb/Core/Debugger.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
1 //===-- Debugger.h ----------------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef LLDB_CORE_DEBUGGER_H
10 #define LLDB_CORE_DEBUGGER_H
11 
12 #include <cstdint>
13 
14 #include <memory>
15 #include <optional>
16 #include <vector>
17 
18 #include "lldb/Core/DebuggerEvents.h"
19 #include "lldb/Core/FormatEntity.h"
20 #include "lldb/Core/IOHandler.h"
21 #include "lldb/Core/SourceManager.h"
22 #include "lldb/Core/Statusline.h"
23 #include "lldb/Core/StructuredDataImpl.h"
24 #include "lldb/Core/Telemetry.h"
25 #include "lldb/Core/UserSettingsController.h"
26 #include "lldb/Host/HostThread.h"
27 #include "lldb/Host/StreamFile.h"
28 #include "lldb/Host/Terminal.h"
29 #include "lldb/Target/ExecutionContext.h"
30 #include "lldb/Target/Platform.h"
31 #include "lldb/Target/TargetList.h"
32 #include "lldb/Utility/Broadcaster.h"
33 #include "lldb/Utility/ConstString.h"
34 #include "lldb/Utility/Diagnostics.h"
35 #include "lldb/Utility/FileSpec.h"
36 #include "lldb/Utility/Status.h"
37 #include "lldb/Utility/StructuredData.h"
38 #include "lldb/Utility/UserID.h"
39 #include "lldb/lldb-defines.h"
40 #include "lldb/lldb-enumerations.h"
41 #include "lldb/lldb-forward.h"
42 #include "lldb/lldb-private-enumerations.h"
43 #include "lldb/lldb-private-types.h"
44 #include "lldb/lldb-types.h"
45 
46 #include "llvm/ADT/ArrayRef.h"
47 #include "llvm/ADT/SmallVector.h"
48 #include "llvm/ADT/StringMap.h"
49 #include "llvm/ADT/StringRef.h"
50 #include "llvm/Support/DynamicLibrary.h"
51 #include "llvm/Support/FormatVariadic.h"
52 #include "llvm/Support/Threading.h"
53 
54 #include <cassert>
55 #include <cstddef>
56 #include <cstdio>
57 
58 namespace llvm {
59 class raw_ostream;
60 class ThreadPoolInterface;
61 } // namespace llvm
62 
63 namespace lldb_private {
64 class Address;
65 class CallbackLogHandler;
66 class CommandInterpreter;
67 class LogHandler;
68 class Process;
69 class Stream;
70 class SymbolContext;
71 class Target;
72 
73 /// \class Debugger Debugger.h "lldb/Core/Debugger.h"
74 /// A class to manage flag bits.
75 ///
76 /// Provides a global root objects for the debugger core.
77 
78 class Debugger : public std::enable_shared_from_this<Debugger>,
79                  public UserID,
80                  public Properties {
81 public:
82   using DebuggerList = std::vector<lldb::DebuggerSP>;
83 
84   static llvm::StringRef GetStaticBroadcasterClass();
85 
86   /// Get the public broadcaster for this debugger.
GetBroadcaster()87   Broadcaster &GetBroadcaster() { return m_broadcaster; }
GetBroadcaster()88   const Broadcaster &GetBroadcaster() const { return m_broadcaster; }
89 
90   ~Debugger() override;
91 
92   static lldb::DebuggerSP
93   CreateInstance(lldb::LogOutputCallback log_callback = nullptr,
94                  void *baton = nullptr);
95 
96   static lldb::TargetSP FindTargetWithProcessID(lldb::pid_t pid);
97 
98   static lldb::TargetSP FindTargetWithProcess(Process *process);
99 
100   static void Initialize(LoadPluginCallbackType load_plugin_callback);
101 
102   static void Terminate();
103 
104   static void SettingsInitialize();
105 
106   static void SettingsTerminate();
107 
108   static void Destroy(lldb::DebuggerSP &debugger_sp);
109 
110   static lldb::DebuggerSP FindDebuggerWithID(lldb::user_id_t id);
111 
112   static lldb::DebuggerSP
113   FindDebuggerWithInstanceName(llvm::StringRef instance_name);
114 
115   static size_t GetNumDebuggers();
116 
117   static lldb::DebuggerSP GetDebuggerAtIndex(size_t index);
118 
119   static bool FormatDisassemblerAddress(const FormatEntity::Entry *format,
120                                         const SymbolContext *sc,
121                                         const SymbolContext *prev_sc,
122                                         const ExecutionContext *exe_ctx,
123                                         const Address *addr, Stream &s);
124 
125   static void AssertCallback(llvm::StringRef message, llvm::StringRef backtrace,
126                              llvm::StringRef prompt);
127 
128   void Clear();
129 
130   void DispatchClientTelemetry(const lldb_private::StructuredDataImpl &entry);
131 
132   bool GetAsyncExecution();
133 
134   void SetAsyncExecution(bool async);
135 
GetInputFileSP()136   lldb::FileSP GetInputFileSP() { return m_input_file_sp; }
GetInputFile()137   File &GetInputFile() { return *m_input_file_sp; }
138 
GetOutputFileSP()139   lldb::FileSP GetOutputFileSP() {
140     return m_output_stream_sp->GetUnlockedFileSP();
141   }
142 
GetErrorFileSP()143   lldb::FileSP GetErrorFileSP() {
144     return m_error_stream_sp->GetUnlockedFileSP();
145   }
146 
147   Status SetInputString(const char *data);
148 
149   void SetInputFile(lldb::FileSP file);
150 
151   void SetOutputFile(lldb::FileSP file);
152 
153   void SetErrorFile(lldb::FileSP file);
154 
155   void SaveInputTerminalState();
156 
157   void RestoreInputTerminalState();
158 
159   lldb::StreamUP GetAsyncOutputStream();
160 
161   lldb::StreamUP GetAsyncErrorStream();
162 
GetCommandInterpreter()163   CommandInterpreter &GetCommandInterpreter() {
164     assert(m_command_interpreter_up.get());
165     return *m_command_interpreter_up;
166   }
167 
168   ScriptInterpreter *
169   GetScriptInterpreter(bool can_create = true,
170                        std::optional<lldb::ScriptLanguage> language = {});
171 
GetListener()172   lldb::ListenerSP GetListener() { return m_listener_sp; }
173 
174   // This returns the Debugger's scratch source manager.  It won't be able to
175   // look up files in debug information, but it can look up files by absolute
176   // path and display them to you. To get the target's source manager, call
177   // GetSourceManager on the target instead.
178   SourceManager &GetSourceManager();
179 
GetSelectedTarget()180   lldb::TargetSP GetSelectedTarget() {
181     return m_target_list.GetSelectedTarget();
182   }
183 
184   ExecutionContext GetSelectedExecutionContext();
185   /// Get accessor for the target list.
186   ///
187   /// The target list is part of the global debugger object. This the single
188   /// debugger shared instance to control where targets get created and to
189   /// allow for tracking and searching for targets based on certain criteria.
190   ///
191   /// \return
192   ///     A global shared target list.
GetTargetList()193   TargetList &GetTargetList() { return m_target_list; }
194 
GetPlatformList()195   PlatformList &GetPlatformList() { return m_platform_list; }
196 
197   void DispatchInputInterrupt();
198 
199   void DispatchInputEndOfFile();
200 
201   // If any of the streams are not set, set them to the in/out/err stream of
202   // the top most input reader to ensure they at least have something
203   void AdoptTopIOHandlerFilesIfInvalid(lldb::FileSP &in,
204                                        lldb::LockableStreamFileSP &out,
205                                        lldb::LockableStreamFileSP &err);
206 
207   /// Run the given IO handler and return immediately.
208   void RunIOHandlerAsync(const lldb::IOHandlerSP &reader_sp,
209                          bool cancel_top_handler = true);
210 
211   /// Run the given IO handler and block until it's complete.
212   void RunIOHandlerSync(const lldb::IOHandlerSP &reader_sp);
213 
214   ///  Remove the given IO handler if it's currently active.
215   bool RemoveIOHandler(const lldb::IOHandlerSP &reader_sp);
216 
217   bool IsTopIOHandler(const lldb::IOHandlerSP &reader_sp);
218 
219   bool CheckTopIOHandlerTypes(IOHandler::Type top_type,
220                               IOHandler::Type second_top_type);
221 
222   void PrintAsync(const char *s, size_t len, bool is_stdout);
223 
224   llvm::StringRef GetTopIOHandlerControlSequence(char ch);
225 
226   const char *GetIOHandlerCommandPrefix();
227 
228   const char *GetIOHandlerHelpPrologue();
229 
230   void RefreshIOHandler();
231 
232   void ClearIOHandlers();
233 
234   bool EnableLog(llvm::StringRef channel,
235                  llvm::ArrayRef<const char *> categories,
236                  llvm::StringRef log_file, uint32_t log_options,
237                  size_t buffer_size, LogHandlerKind log_handler_kind,
238                  llvm::raw_ostream &error_stream);
239 
240   void SetLoggingCallback(lldb::LogOutputCallback log_callback, void *baton);
241 
242   Status SetPropertyValue(const ExecutionContext *exe_ctx,
243                           VarSetOperationType op, llvm::StringRef property_path,
244                           llvm::StringRef value) override;
245 
246   bool GetAutoConfirm() const;
247 
248   FormatEntity::Entry GetDisassemblyFormat() const;
249 
250   FormatEntity::Entry GetFrameFormat() const;
251 
252   FormatEntity::Entry GetFrameFormatUnique() const;
253 
254   uint64_t GetStopDisassemblyMaxSize() const;
255 
256   FormatEntity::Entry GetThreadFormat() const;
257 
258   FormatEntity::Entry GetThreadStopFormat() const;
259 
260   lldb::ScriptLanguage GetScriptLanguage() const;
261 
262   bool SetScriptLanguage(lldb::ScriptLanguage script_lang);
263 
264   lldb::LanguageType GetREPLLanguage() const;
265 
266   bool SetREPLLanguage(lldb::LanguageType repl_lang);
267 
268   uint64_t GetTerminalWidth() const;
269 
270   bool SetTerminalWidth(uint64_t term_width);
271 
272   uint64_t GetTerminalHeight() const;
273 
274   bool SetTerminalHeight(uint64_t term_height);
275 
276   llvm::StringRef GetPrompt() const;
277 
278   llvm::StringRef GetPromptAnsiPrefix() const;
279 
280   llvm::StringRef GetPromptAnsiSuffix() const;
281 
282   void SetPrompt(llvm::StringRef p);
283   void SetPrompt(const char *) = delete;
284 
285   bool GetUseExternalEditor() const;
286   bool SetUseExternalEditor(bool use_external_editor_p);
287 
288   llvm::StringRef GetExternalEditor() const;
289 
290   bool SetExternalEditor(llvm::StringRef editor);
291 
292   bool GetUseColor() const;
293 
294   bool SetUseColor(bool use_color);
295 
296   bool GetShowProgress() const;
297 
298   bool SetShowProgress(bool show_progress);
299 
300   bool GetShowStatusline() const;
301 
302   FormatEntity::Entry GetStatuslineFormat() const;
303   bool SetStatuslineFormat(const FormatEntity::Entry &format);
304 
305   llvm::StringRef GetSeparator() const;
306   bool SetSeparator(llvm::StringRef s);
307 
308   llvm::StringRef GetShowProgressAnsiPrefix() const;
309 
310   llvm::StringRef GetShowProgressAnsiSuffix() const;
311 
312   llvm::StringRef GetDisabledAnsiPrefix() const;
313 
314   llvm::StringRef GetDisabledAnsiSuffix() const;
315 
316   bool GetUseAutosuggestion() const;
317 
318   llvm::StringRef GetAutosuggestionAnsiPrefix() const;
319 
320   llvm::StringRef GetAutosuggestionAnsiSuffix() const;
321 
322   llvm::StringRef GetRegexMatchAnsiPrefix() const;
323 
324   llvm::StringRef GetRegexMatchAnsiSuffix() const;
325 
326   bool GetShowDontUsePoHint() const;
327 
328   bool GetUseSourceCache() const;
329 
330   bool SetUseSourceCache(bool use_source_cache);
331 
332   bool GetHighlightSource() const;
333 
334   lldb::StopShowColumn GetStopShowColumn() const;
335 
336   llvm::StringRef GetStopShowColumnAnsiPrefix() const;
337 
338   llvm::StringRef GetStopShowColumnAnsiSuffix() const;
339 
340   uint64_t GetStopSourceLineCount(bool before) const;
341 
342   lldb::StopDisassemblyType GetStopDisassemblyDisplay() const;
343 
344   uint64_t GetDisassemblyLineCount() const;
345 
346   llvm::StringRef GetStopShowLineMarkerAnsiPrefix() const;
347 
348   llvm::StringRef GetStopShowLineMarkerAnsiSuffix() const;
349 
350   bool GetAutoOneLineSummaries() const;
351 
352   bool GetAutoIndent() const;
353 
354   bool SetAutoIndent(bool b);
355 
356   bool GetPrintDecls() const;
357 
358   bool SetPrintDecls(bool b);
359 
360   uint64_t GetTabSize() const;
361 
362   bool SetTabSize(uint64_t tab_size);
363 
364   lldb::DWIMPrintVerbosity GetDWIMPrintVerbosity() const;
365 
366   bool GetEscapeNonPrintables() const;
367 
368   bool GetNotifyVoid() const;
369 
GetInstanceName()370   const std::string &GetInstanceName() const { return m_instance_name; }
371 
372   bool GetShowInlineDiagnostics() const;
373 
374   bool SetShowInlineDiagnostics(bool);
375 
376   bool LoadPlugin(const FileSpec &spec, Status &error);
377 
378   void RunIOHandlers();
379 
380   bool IsForwardingEvents();
381 
382   void EnableForwardEvents(const lldb::ListenerSP &listener_sp);
383 
384   void CancelForwardEvents(const lldb::ListenerSP &listener_sp);
385 
IsHandlingEvents()386   bool IsHandlingEvents() const { return m_event_handler_thread.IsJoinable(); }
387 
388   Status RunREPL(lldb::LanguageType language, const char *repl_options);
389 
390   /// Interruption in LLDB:
391   ///
392   /// This is a voluntary interruption mechanism, not preemptive.  Parts of lldb
393   /// that do work that can be safely interrupted call
394   /// Debugger::InterruptRequested and if that returns true, they should return
395   /// at a safe point, shortcutting the rest of the work they were to do.
396   ///
397   /// lldb clients can both offer a CommandInterpreter (through
398   /// RunCommandInterpreter) and use the SB API's for their own purposes, so it
399   /// is convenient to separate "interrupting the CommandInterpreter execution"
400   /// and interrupting the work it is doing with the SB API's.  So there are two
401   /// ways to cause an interrupt:
402   ///   * CommandInterpreter::InterruptCommand: Interrupts the command currently
403   ///     running in the command interpreter IOHandler thread
404   ///   * Debugger::RequestInterrupt: Interrupts are active on anything but the
405   ///     CommandInterpreter thread till CancelInterruptRequest is called.
406   ///
407   /// Since the two checks are mutually exclusive, however, it's also convenient
408   /// to have just one function to check the interrupt state.
409 
410   /// Bump the "interrupt requested" count on the debugger to support
411   /// cooperative interruption.  If this is non-zero, InterruptRequested will
412   /// return true.  Interruptible operations are expected to query the
413   /// InterruptRequested API periodically, and interrupt what they were doing
414   /// if it returns \b true.
415   ///
416   void RequestInterrupt();
417 
418   /// Decrement the "interrupt requested" counter.
419   void CancelInterruptRequest();
420 
421   /// Redraw the statusline if enabled.
422   void RedrawStatusline(bool update = true);
423 
424   /// This is the correct way to query the state of Interruption.
425   /// If you are on the RunCommandInterpreter thread, it will check the
426   /// command interpreter state, and if it is on another thread it will
427   /// check the debugger Interrupt Request state.
428   /// \param[in] cur_func
429   /// For reporting if the interruption was requested.  Don't provide this by
430   /// hand, use INTERRUPT_REQUESTED so this gets done consistently.
431   ///
432   /// \param[in] formatv
433   /// A formatv string for the interrupt message.  If the elements of the
434   /// message are expensive to compute, you can use the no-argument form of
435   /// InterruptRequested, then make up the report using REPORT_INTERRUPTION.
436   ///
437   /// \return
438   ///  A boolean value, if \b true an interruptible operation should interrupt
439   ///  itself.
440   template <typename... Args>
InterruptRequested(const char * cur_func,const char * formatv,Args &&...args)441   bool InterruptRequested(const char *cur_func, const char *formatv,
442                           Args &&...args) {
443     bool ret_val = InterruptRequested();
444     if (ret_val) {
445       if (!formatv)
446         formatv = "Unknown message";
447       if (!cur_func)
448         cur_func = "<UNKNOWN>";
449       ReportInterruption(InterruptionReport(
450           cur_func, llvm::formatv(formatv, std::forward<Args>(args)...)));
451     }
452     return ret_val;
453   }
454 
455   /// This handy define will keep you from having to generate a report for the
456   /// interruption by hand.  Use this except in the case where the arguments to
457   /// the message description are expensive to compute.
458 #define INTERRUPT_REQUESTED(debugger, ...)                                     \
459   (debugger).InterruptRequested(__func__, __VA_ARGS__)
460 
461   // This form just queries for whether to interrupt, and does no reporting:
462   bool InterruptRequested();
463 
464   // FIXME: Do we want to capture a backtrace at the interruption point?
465   class InterruptionReport {
466   public:
InterruptionReport(std::string function_name,std::string description)467     InterruptionReport(std::string function_name, std::string description)
468         : m_function_name(std::move(function_name)),
469           m_description(std::move(description)),
470           m_interrupt_time(std::chrono::system_clock::now()),
471           m_thread_id(llvm::get_threadid()) {}
472 
473     InterruptionReport(std::string function_name,
474                        const llvm::formatv_object_base &payload);
475 
476     template <typename... Args>
InterruptionReport(std::string function_name,const char * format,Args &&...args)477     InterruptionReport(std::string function_name, const char *format,
478                        Args &&...args)
479         : InterruptionReport(
480               function_name,
481               llvm::formatv(format, std::forward<Args>(args)...)) {}
482 
483     std::string m_function_name;
484     std::string m_description;
485     const std::chrono::time_point<std::chrono::system_clock> m_interrupt_time;
486     const uint64_t m_thread_id;
487   };
488   void ReportInterruption(const InterruptionReport &report);
489 #define REPORT_INTERRUPTION(debugger, ...)                                     \
490   (debugger).ReportInterruption(                                               \
491       Debugger::InterruptionReport(__func__, __VA_ARGS__))
492 
493   static DebuggerList DebuggersRequestingInterruption();
494 
495 public:
496   // This is for use in the command interpreter, when you either want the
497   // selected target, or if no target is present you want to prime the dummy
498   // target with entities that will be copied over to new targets.
499   Target &GetSelectedOrDummyTarget(bool prefer_dummy = false);
GetDummyTarget()500   Target &GetDummyTarget() { return *m_dummy_target_sp; }
501 
GetBroadcasterManager()502   lldb::BroadcasterManagerSP GetBroadcasterManager() {
503     return m_broadcaster_manager_sp;
504   }
505 
506   /// Shared thread pool. Use only with ThreadPoolTaskGroup.
507   static llvm::ThreadPoolInterface &GetThreadPool();
508 
509   /// Report warning events.
510   ///
511   /// Warning events will be delivered to any debuggers that have listeners
512   /// for the eBroadcastBitWarning.
513   ///
514   /// \param[in] message
515   ///   The warning message to be reported.
516   ///
517   /// \param [in] debugger_id
518   ///   If this optional parameter has a value, it indicates the unique
519   ///   debugger identifier that this diagnostic should be delivered to. If
520   ///   this optional parameter does not have a value, the diagnostic event
521   ///   will be delivered to all debuggers.
522   ///
523   /// \param [in] once
524   ///   If a pointer is passed to a std::once_flag, then it will be used to
525   ///   ensure the given warning is only broadcast once.
526   static void
527   ReportWarning(std::string message,
528                 std::optional<lldb::user_id_t> debugger_id = std::nullopt,
529                 std::once_flag *once = nullptr);
530 
531   /// Report error events.
532   ///
533   /// Error events will be delivered to any debuggers that have listeners
534   /// for the eBroadcastBitError.
535   ///
536   /// \param[in] message
537   ///   The error message to be reported.
538   ///
539   /// \param [in] debugger_id
540   ///   If this optional parameter has a value, it indicates the unique
541   ///   debugger identifier that this diagnostic should be delivered to. If
542   ///   this optional parameter does not have a value, the diagnostic event
543   ///   will be delivered to all debuggers.
544   ///
545   /// \param [in] once
546   ///   If a pointer is passed to a std::once_flag, then it will be used to
547   ///   ensure the given error is only broadcast once.
548   static void
549   ReportError(std::string message,
550               std::optional<lldb::user_id_t> debugger_id = std::nullopt,
551               std::once_flag *once = nullptr);
552 
553   /// Report info events.
554   ///
555   /// Unlike warning and error events, info events are not broadcast but are
556   /// logged for diagnostic purposes.
557   ///
558   /// \param[in] message
559   ///   The info message to be reported.
560   ///
561   /// \param [in] debugger_id
562   ///   If this optional parameter has a value, it indicates this diagnostic is
563   ///   associated with a unique debugger instance.
564   ///
565   /// \param [in] once
566   ///   If a pointer is passed to a std::once_flag, then it will be used to
567   ///   ensure the given info is only logged once.
568   static void
569   ReportInfo(std::string message,
570              std::optional<lldb::user_id_t> debugger_id = std::nullopt,
571              std::once_flag *once = nullptr);
572 
573   static void ReportSymbolChange(const ModuleSpec &module_spec);
574 
575   /// DEPRECATED: We used to only support one Destroy callback. Now that we
576   /// support Add and Remove, you should only remove callbacks that you added.
577   /// Use Add and Remove instead.
578   ///
579   /// Clear all previously added callbacks and only add the given one.
580   void
581   SetDestroyCallback(lldb_private::DebuggerDestroyCallback destroy_callback,
582                      void *baton);
583 
584   /// Add a callback for when the debugger is destroyed. Return a token, which
585   /// can be used to remove said callback. Multiple callbacks can be added by
586   /// calling this function multiple times, and will be invoked in FIFO order.
587   lldb::callback_token_t
588   AddDestroyCallback(lldb_private::DebuggerDestroyCallback destroy_callback,
589                      void *baton);
590 
591   /// Remove the specified callback. Return true if successful.
592   bool RemoveDestroyCallback(lldb::callback_token_t token);
593 
594   /// Manually start the global event handler thread. It is useful to plugins
595   /// that directly use the \a lldb_private namespace and want to use the
596   /// debugger's default event handler thread instead of defining their own.
597   bool StartEventHandlerThread();
598 
599   /// Manually stop the debugger's default event handler.
600   void StopEventHandlerThread();
601 
602   /// Force flushing the process's pending stdout and stderr to the debugger's
603   /// asynchronous stdout and stderr streams.
604   void FlushProcessOutput(Process &process, bool flush_stdout,
605                           bool flush_stderr);
606 
GetSourceFileCache()607   SourceManager::SourceFileCache &GetSourceFileCache() {
608     return m_source_file_cache;
609   }
610 
611   struct ProgressReport {
612     uint64_t id;
613     uint64_t completed;
614     uint64_t total;
615     std::string message;
616   };
617   std::optional<ProgressReport> GetCurrentProgressReport() const;
618 
619 protected:
620   friend class CommandInterpreter;
621   friend class REPL;
622   friend class Progress;
623   friend class ProgressManager;
624   friend class Statusline;
625 
626   /// Report progress events.
627   ///
628   /// Progress events will be delivered to any debuggers that have listeners
629   /// for the eBroadcastBitProgress. This function is called by the
630   /// lldb_private::Progress class to deliver the events to any debuggers that
631   /// qualify.
632   ///
633   /// \param [in] progress_id
634   ///   The unique integer identifier for the progress to report.
635   ///
636   /// \param[in] message
637   ///   The title of the progress dialog to display in the UI.
638   ///
639   /// \param [in] completed
640   ///   The amount of work completed. If \a completed is zero, then this event
641   ///   is a progress started event. If \a completed is equal to \a total, then
642   ///   this event is a progress end event. Otherwise completed indicates the
643   ///   current progress compare to the total value.
644   ///
645   /// \param [in] total
646   ///   The total amount of work units that need to be completed. If this value
647   ///   is UINT64_MAX, then an indeterminate progress indicator should be
648   ///   displayed.
649   ///
650   /// \param [in] debugger_id
651   ///   If this optional parameter has a value, it indicates the unique
652   ///   debugger identifier that this progress should be delivered to. If this
653   ///   optional parameter does not have a value, the progress will be
654   ///   delivered to all debuggers.
655   static void
656   ReportProgress(uint64_t progress_id, std::string title, std::string details,
657                  uint64_t completed, uint64_t total,
658                  std::optional<lldb::user_id_t> debugger_id,
659                  uint32_t progress_category_bit = lldb::eBroadcastBitProgress);
660 
661   static void ReportDiagnosticImpl(lldb::Severity severity, std::string message,
662                                    std::optional<lldb::user_id_t> debugger_id,
663                                    std::once_flag *once);
664 
665   void HandleDestroyCallback();
666 
667   void PrintProgress(const ProgressEventData &data);
668 
669   /// Except for Debugger and IOHandler, GetOutputStreamSP and GetErrorStreamSP
670   /// should not be used directly. Use GetAsyncOutputStream and
671   /// GetAsyncErrorStream instead.
672   /// @{
GetOutputStreamSP()673   lldb::LockableStreamFileSP GetOutputStreamSP() { return m_output_stream_sp; }
GetErrorStreamSP()674   lldb::LockableStreamFileSP GetErrorStreamSP() { return m_error_stream_sp; }
675   /// @}
676 
677   bool StatuslineSupported();
678 
679   void PushIOHandler(const lldb::IOHandlerSP &reader_sp,
680                      bool cancel_top_handler = true);
681 
682   bool PopIOHandler(const lldb::IOHandlerSP &reader_sp);
683 
684   bool HasIOHandlerThread() const;
685 
686   bool StartIOHandlerThread();
687 
688   void StopIOHandlerThread();
689 
690   // Sets the IOHandler thread to the new_thread, and returns
691   // the previous IOHandler thread.
692   HostThread SetIOHandlerThread(HostThread &new_thread);
693 
694   void JoinIOHandlerThread();
695 
696   bool IsIOHandlerThreadCurrentThread() const;
697 
698   lldb::thread_result_t IOHandlerThread();
699 
700   lldb::thread_result_t DefaultEventHandler();
701 
702   void HandleBreakpointEvent(const lldb::EventSP &event_sp);
703 
704   void HandleProcessEvent(const lldb::EventSP &event_sp);
705 
706   void HandleThreadEvent(const lldb::EventSP &event_sp);
707 
708   void HandleProgressEvent(const lldb::EventSP &event_sp);
709 
710   void HandleDiagnosticEvent(const lldb::EventSP &event_sp);
711 
712   // Ensures two threads don't attempt to flush process output in parallel.
713   std::mutex m_output_flush_mutex;
714 
715   void InstanceInitialize();
716 
717   // these should never be NULL
718   lldb::FileSP m_input_file_sp;
719   lldb::LockableStreamFileSP m_output_stream_sp;
720   lldb::LockableStreamFileSP m_error_stream_sp;
721   LockableStreamFile::Mutex m_output_mutex;
722 
723   lldb::BroadcasterManagerSP m_broadcaster_manager_sp; // The debugger acts as a
724                                                        // broadcaster manager of
725                                                        // last resort.
726   // It needs to get constructed before the target_list or any other member
727   // that might want to broadcast through the debugger.
728 
729   TerminalState m_terminal_state;
730   TargetList m_target_list;
731 
732   PlatformList m_platform_list;
733   lldb::ListenerSP m_listener_sp;
734   std::unique_ptr<SourceManager> m_source_manager_up; // This is a scratch
735                                                       // source manager that we
736                                                       // return if we have no
737                                                       // targets.
738   SourceManager::SourceFileCache m_source_file_cache; // All the source managers
739                                                       // for targets created in
740                                                       // this debugger used this
741                                                       // shared
742                                                       // source file cache.
743   std::unique_ptr<CommandInterpreter> m_command_interpreter_up;
744 
745   std::recursive_mutex m_script_interpreter_mutex;
746   std::array<lldb::ScriptInterpreterSP, lldb::eScriptLanguageUnknown>
747       m_script_interpreters;
748 
749   IOHandlerStack m_io_handler_stack;
750   std::recursive_mutex m_io_handler_synchronous_mutex;
751 
752   /// Mutex protecting the m_statusline member.
753   std::mutex m_statusline_mutex;
754   std::optional<Statusline> m_statusline;
755 
756   llvm::StringMap<std::weak_ptr<LogHandler>> m_stream_handlers;
757   std::shared_ptr<CallbackLogHandler> m_callback_handler_sp;
758   const std::string m_instance_name;
759   static LoadPluginCallbackType g_load_plugin_callback;
760   typedef std::vector<llvm::sys::DynamicLibrary> LoadedPluginsList;
761   LoadedPluginsList m_loaded_plugins;
762   HostThread m_event_handler_thread;
763   HostThread m_io_handler_thread;
764   Broadcaster m_sync_broadcaster; ///< Private debugger synchronization.
765   Broadcaster m_broadcaster;      ///< Public Debugger event broadcaster.
766   lldb::ListenerSP m_forward_listener_sp;
767   llvm::once_flag m_clear_once;
768   lldb::TargetSP m_dummy_target_sp;
769   Diagnostics::CallbackID m_diagnostics_callback_id;
770 
771   /// Bookkeeping for command line progress events.
772   /// @{
773   llvm::SmallVector<ProgressReport, 4> m_progress_reports;
774   mutable std::mutex m_progress_reports_mutex;
775   /// @}
776 
777   std::mutex m_destroy_callback_mutex;
778   lldb::callback_token_t m_destroy_callback_next_token = 0;
779   struct DestroyCallbackInfo {
DestroyCallbackInfoDestroyCallbackInfo780     DestroyCallbackInfo() {}
DestroyCallbackInfoDestroyCallbackInfo781     DestroyCallbackInfo(lldb::callback_token_t token,
782                         lldb_private::DebuggerDestroyCallback callback,
783                         void *baton)
784         : token(token), callback(callback), baton(baton) {}
785     lldb::callback_token_t token;
786     lldb_private::DebuggerDestroyCallback callback;
787     void *baton;
788   };
789   llvm::SmallVector<DestroyCallbackInfo, 2> m_destroy_callbacks;
790 
791   uint32_t m_interrupt_requested = 0; ///< Tracks interrupt requests
792   std::mutex m_interrupt_mutex;
793 
794   // Events for m_sync_broadcaster
795   enum {
796     eBroadcastBitEventThreadIsListening = (1 << 0),
797   };
798 
799 private:
800   // Use Debugger::CreateInstance() to get a shared pointer to a new debugger
801   // object
802   Debugger(lldb::LogOutputCallback m_log_callback, void *baton);
803 
804   Debugger(const Debugger &) = delete;
805   const Debugger &operator=(const Debugger &) = delete;
806 };
807 
808 } // namespace lldb_private
809 
810 #endif // LLDB_CORE_DEBUGGER_H
811