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