| //===-- Debugger.h ----------------------------------------------*- C++ -*-===// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #ifndef liblldb_Debugger_h_ |
| #define liblldb_Debugger_h_ |
| |
| // C Includes |
| #include <stdint.h> |
| |
| // C++ Includes |
| #include <memory> |
| #include <map> |
| #include <mutex> |
| #include <vector> |
| |
| // Other libraries and framework includes |
| // Project includes |
| #include "lldb/lldb-public.h" |
| #include "lldb/Core/Broadcaster.h" |
| #include "lldb/Core/FormatEntity.h" |
| #include "lldb/Core/IOHandler.h" |
| #include "lldb/Core/Listener.h" |
| #include "lldb/Core/SourceManager.h" |
| #include "lldb/Core/UserID.h" |
| #include "lldb/Core/UserSettingsController.h" |
| #include "lldb/Host/HostThread.h" |
| #include "lldb/Host/Terminal.h" |
| #include "lldb/Target/Platform.h" |
| #include "lldb/Target/TargetList.h" |
| |
| namespace llvm |
| { |
| namespace sys |
| { |
| class DynamicLibrary; |
| } // namespace sys |
| } // namespace llvm |
| |
| namespace lldb_private { |
| |
| //---------------------------------------------------------------------- |
| /// @class Debugger Debugger.h "lldb/Core/Debugger.h" |
| /// @brief A class to manage flag bits. |
| /// |
| /// Provides a global root objects for the debugger core. |
| //---------------------------------------------------------------------- |
| |
| class Debugger : |
| public std::enable_shared_from_this<Debugger>, |
| public UserID, |
| public Properties |
| { |
| friend class SourceManager; // For GetSourceFileCache. |
| |
| public: |
| ~Debugger() override; |
| |
| static lldb::DebuggerSP |
| CreateInstance(lldb::LogOutputCallback log_callback = nullptr, void *baton = nullptr); |
| |
| static lldb::TargetSP |
| FindTargetWithProcessID (lldb::pid_t pid); |
| |
| static lldb::TargetSP |
| FindTargetWithProcess (Process *process); |
| |
| static void |
| Initialize(LoadPluginCallbackType load_plugin_callback); |
| |
| static void |
| Terminate(); |
| |
| static void |
| SettingsInitialize (); |
| |
| static void |
| SettingsTerminate (); |
| |
| static void |
| Destroy (lldb::DebuggerSP &debugger_sp); |
| |
| static lldb::DebuggerSP |
| FindDebuggerWithID(lldb::user_id_t id); |
| |
| static lldb::DebuggerSP |
| FindDebuggerWithInstanceName(const ConstString &instance_name); |
| |
| static size_t |
| GetNumDebuggers(); |
| |
| static lldb::DebuggerSP |
| GetDebuggerAtIndex(size_t index); |
| |
| static bool |
| FormatDisassemblerAddress(const FormatEntity::Entry *format, |
| const SymbolContext *sc, |
| const SymbolContext *prev_sc, |
| const ExecutionContext *exe_ctx, |
| const Address *addr, |
| Stream &s); |
| |
| void Clear(); |
| |
| bool |
| GetAsyncExecution (); |
| |
| void |
| SetAsyncExecution (bool async); |
| |
| lldb::StreamFileSP |
| GetInputFile () |
| { |
| return m_input_file_sp; |
| } |
| |
| lldb::StreamFileSP |
| GetOutputFile () |
| { |
| return m_output_file_sp; |
| } |
| |
| lldb::StreamFileSP |
| GetErrorFile () |
| { |
| return m_error_file_sp; |
| } |
| |
| void |
| SetInputFileHandle (FILE *fh, bool tranfer_ownership); |
| |
| void |
| SetOutputFileHandle (FILE *fh, bool tranfer_ownership); |
| |
| void |
| SetErrorFileHandle (FILE *fh, bool tranfer_ownership); |
| |
| void |
| SaveInputTerminalState(); |
| |
| void |
| RestoreInputTerminalState(); |
| |
| lldb::StreamSP |
| GetAsyncOutputStream (); |
| |
| lldb::StreamSP |
| GetAsyncErrorStream (); |
| |
| CommandInterpreter & |
| GetCommandInterpreter () |
| { |
| assert (m_command_interpreter_ap.get()); |
| return *m_command_interpreter_ap; |
| } |
| |
| lldb::ListenerSP |
| GetListener () |
| { |
| return m_listener_sp; |
| } |
| |
| // This returns the Debugger's scratch source manager. It won't be able to look up files in debug |
| // information, but it can look up files by absolute path and display them to you. |
| // To get the target's source manager, call GetSourceManager on the target instead. |
| SourceManager & |
| GetSourceManager (); |
| |
| lldb::TargetSP |
| GetSelectedTarget () |
| { |
| return m_target_list.GetSelectedTarget (); |
| } |
| |
| ExecutionContext |
| GetSelectedExecutionContext(); |
| //------------------------------------------------------------------ |
| /// Get accessor for the target list. |
| /// |
| /// The target list is part of the global debugger object. This |
| /// the single debugger shared instance to control where targets |
| /// get created and to allow for tracking and searching for targets |
| /// based on certain criteria. |
| /// |
| /// @return |
| /// A global shared target list. |
| //------------------------------------------------------------------ |
| TargetList & |
| GetTargetList () |
| { |
| return m_target_list; |
| } |
| |
| PlatformList & |
| GetPlatformList () |
| { |
| return m_platform_list; |
| } |
| |
| void |
| DispatchInputInterrupt (); |
| |
| void |
| DispatchInputEndOfFile (); |
| |
| //------------------------------------------------------------------ |
| // If any of the streams are not set, set them to the in/out/err |
| // stream of the top most input reader to ensure they at least have |
| // something |
| //------------------------------------------------------------------ |
| void |
| AdoptTopIOHandlerFilesIfInvalid (lldb::StreamFileSP &in, |
| lldb::StreamFileSP &out, |
| lldb::StreamFileSP &err); |
| |
| void |
| PushIOHandler (const lldb::IOHandlerSP& reader_sp); |
| |
| bool |
| PopIOHandler (const lldb::IOHandlerSP& reader_sp); |
| |
| // Synchronously run an input reader until it is done |
| void |
| RunIOHandler (const lldb::IOHandlerSP& reader_sp); |
| |
| bool |
| IsTopIOHandler (const lldb::IOHandlerSP& reader_sp); |
| |
| bool |
| CheckTopIOHandlerTypes (IOHandler::Type top_type, |
| IOHandler::Type second_top_type); |
| |
| void |
| PrintAsync (const char *s, size_t len, bool is_stdout); |
| |
| ConstString |
| GetTopIOHandlerControlSequence(char ch); |
| |
| const char * |
| GetIOHandlerCommandPrefix(); |
| |
| const char * |
| GetIOHandlerHelpPrologue(); |
| |
| void |
| ClearIOHandlers (); |
| |
| bool |
| GetCloseInputOnEOF () const; |
| |
| void |
| SetCloseInputOnEOF (bool b); |
| |
| bool |
| EnableLog (const char *channel, const char **categories, const char *log_file, uint32_t log_options, Stream &error_stream); |
| |
| void |
| SetLoggingCallback (lldb::LogOutputCallback log_callback, void *baton); |
| |
| //---------------------------------------------------------------------- |
| // Properties Functions |
| //---------------------------------------------------------------------- |
| enum StopDisassemblyType |
| { |
| eStopDisassemblyTypeNever = 0, |
| eStopDisassemblyTypeNoDebugInfo, |
| eStopDisassemblyTypeNoSource, |
| eStopDisassemblyTypeAlways |
| }; |
| |
| Error |
| SetPropertyValue(const ExecutionContext *exe_ctx, |
| VarSetOperationType op, |
| const char *property_path, |
| const char *value) override; |
| |
| bool |
| GetAutoConfirm () const; |
| |
| const FormatEntity::Entry * |
| GetDisassemblyFormat() const; |
| |
| const FormatEntity::Entry * |
| GetFrameFormat() const; |
| |
| const FormatEntity::Entry * |
| GetThreadFormat() const; |
| |
| lldb::ScriptLanguage |
| GetScriptLanguage() const; |
| |
| bool |
| SetScriptLanguage (lldb::ScriptLanguage script_lang); |
| |
| uint32_t |
| GetTerminalWidth () const; |
| |
| bool |
| SetTerminalWidth (uint32_t term_width); |
| |
| const char * |
| GetPrompt() const; |
| |
| void |
| SetPrompt(const char *p); |
| |
| bool |
| GetUseExternalEditor () const; |
| |
| bool |
| SetUseExternalEditor (bool use_external_editor_p); |
| |
| bool |
| GetUseColor () const; |
| |
| bool |
| SetUseColor (bool use_color); |
| |
| uint32_t |
| GetStopSourceLineCount (bool before) const; |
| |
| StopDisassemblyType |
| GetStopDisassemblyDisplay () const; |
| |
| uint32_t |
| GetDisassemblyLineCount () const; |
| |
| bool |
| GetAutoOneLineSummaries () const; |
| |
| bool |
| GetAutoIndent () const; |
| |
| bool |
| SetAutoIndent (bool b); |
| |
| bool |
| GetPrintDecls () const; |
| |
| bool |
| SetPrintDecls (bool b); |
| |
| uint32_t |
| GetTabSize () const; |
| |
| bool |
| SetTabSize (uint32_t tab_size); |
| |
| bool |
| GetEscapeNonPrintables () const; |
| |
| bool |
| GetNotifyVoid () const; |
| |
| const ConstString & |
| GetInstanceName() |
| { |
| return m_instance_name; |
| } |
| |
| bool |
| LoadPlugin (const FileSpec& spec, Error& error); |
| |
| void |
| ExecuteIOHandlers(); |
| |
| bool |
| IsForwardingEvents (); |
| |
| void |
| EnableForwardEvents (const lldb::ListenerSP &listener_sp); |
| |
| void |
| CancelForwardEvents (const lldb::ListenerSP &listener_sp); |
| |
| bool |
| IsHandlingEvents () const |
| { |
| return m_event_handler_thread.IsJoinable(); |
| } |
| |
| Error |
| RunREPL (lldb::LanguageType language, const char *repl_options); |
| |
| // This is for use in the command interpreter, when you either want the selected target, or if no target |
| // is present you want to prime the dummy target with entities that will be copied over to new targets. |
| Target *GetSelectedOrDummyTarget(bool prefer_dummy = false); |
| Target *GetDummyTarget(); |
| |
| lldb::BroadcasterManagerSP |
| GetBroadcasterManager() |
| { |
| return m_broadcaster_manager_sp; |
| } |
| |
| protected: |
| friend class CommandInterpreter; |
| friend class REPL; |
| |
| bool |
| StartEventHandlerThread(); |
| |
| void |
| StopEventHandlerThread(); |
| |
| static lldb::thread_result_t |
| EventHandlerThread (lldb::thread_arg_t arg); |
| |
| bool |
| HasIOHandlerThread(); |
| |
| bool |
| StartIOHandlerThread(); |
| |
| void |
| StopIOHandlerThread(); |
| |
| void |
| JoinIOHandlerThread(); |
| |
| static lldb::thread_result_t |
| IOHandlerThread (lldb::thread_arg_t arg); |
| |
| void |
| DefaultEventHandler(); |
| |
| void |
| HandleBreakpointEvent (const lldb::EventSP &event_sp); |
| |
| void |
| HandleProcessEvent (const lldb::EventSP &event_sp); |
| |
| void |
| HandleThreadEvent (const lldb::EventSP &event_sp); |
| |
| size_t |
| GetProcessSTDOUT (Process *process, Stream *stream); |
| |
| size_t |
| GetProcessSTDERR (Process *process, Stream *stream); |
| |
| SourceManager::SourceFileCache & |
| GetSourceFileCache () |
| { |
| return m_source_file_cache; |
| } |
| |
| void |
| InstanceInitialize (); |
| |
| lldb::StreamFileSP m_input_file_sp; |
| lldb::StreamFileSP m_output_file_sp; |
| lldb::StreamFileSP m_error_file_sp; |
| |
| lldb::BroadcasterManagerSP m_broadcaster_manager_sp; // The debugger acts as a broadcaster manager of last resort. |
| // It needs to get constructed before the target_list or any other |
| // member that might want to broadcast through the debugger. |
| |
| TerminalState m_terminal_state; |
| TargetList m_target_list; |
| |
| PlatformList m_platform_list; |
| lldb::ListenerSP m_listener_sp; |
| std::unique_ptr<SourceManager> m_source_manager_ap; // This is a scratch source manager that we return if we have no targets. |
| SourceManager::SourceFileCache m_source_file_cache; // All the source managers for targets created in this debugger used this shared |
| // source file cache. |
| std::unique_ptr<CommandInterpreter> m_command_interpreter_ap; |
| |
| IOHandlerStack m_input_reader_stack; |
| typedef std::map<std::string, lldb::StreamWP> LogStreamMap; |
| LogStreamMap m_log_streams; |
| lldb::StreamSP m_log_callback_stream_sp; |
| ConstString m_instance_name; |
| static LoadPluginCallbackType g_load_plugin_callback; |
| typedef std::vector<llvm::sys::DynamicLibrary> LoadedPluginsList; |
| LoadedPluginsList m_loaded_plugins; |
| HostThread m_event_handler_thread; |
| HostThread m_io_handler_thread; |
| Broadcaster m_sync_broadcaster; |
| lldb::ListenerSP m_forward_listener_sp; |
| std::once_flag m_clear_once; |
| |
| //---------------------------------------------------------------------- |
| // Events for m_sync_broadcaster |
| //---------------------------------------------------------------------- |
| enum |
| { |
| eBroadcastBitEventThreadIsListening = (1 << 0), |
| }; |
| |
| private: |
| // Use Debugger::CreateInstance() to get a shared pointer to a new |
| // debugger object |
| Debugger (lldb::LogOutputCallback m_log_callback, void *baton); |
| |
| DISALLOW_COPY_AND_ASSIGN (Debugger); |
| }; |
| |
| } // namespace lldb_private |
| |
| #endif // liblldb_Debugger_h_ |