| //===-- ProcessGDBRemote.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_ProcessGDBRemote_h_ |
| #define liblldb_ProcessGDBRemote_h_ |
| |
| // C Includes |
| |
| // C++ Includes |
| #include <list> |
| #include <vector> |
| |
| // Other libraries and framework includes |
| #include "lldb/Core/ArchSpec.h" |
| #include "lldb/Core/Broadcaster.h" |
| #include "lldb/Core/ConstString.h" |
| #include "lldb/Core/Error.h" |
| #include "lldb/Core/StreamString.h" |
| #include "lldb/Core/StringList.h" |
| #include "lldb/Core/StructuredData.h" |
| #include "lldb/Core/ThreadSafeValue.h" |
| #include "lldb/Host/HostThread.h" |
| #include "lldb/lldb-private-forward.h" |
| #include "lldb/Utility/StringExtractor.h" |
| #include "lldb/Target/Process.h" |
| #include "lldb/Target/Thread.h" |
| |
| #include "GDBRemoteCommunicationClient.h" |
| #include "GDBRemoteRegisterContext.h" |
| |
| namespace lldb_private { |
| namespace process_gdb_remote { |
| |
| class ThreadGDBRemote; |
| |
| class ProcessGDBRemote : public Process |
| { |
| public: |
| //------------------------------------------------------------------ |
| // Constructors and Destructors |
| //------------------------------------------------------------------ |
| static lldb::ProcessSP |
| CreateInstance (Target& target, |
| Listener &listener, |
| const FileSpec *crash_file_path); |
| |
| static void |
| Initialize(); |
| |
| static void |
| DebuggerInitialize (Debugger &debugger); |
| |
| static void |
| Terminate(); |
| |
| static ConstString |
| GetPluginNameStatic(); |
| |
| static const char * |
| GetPluginDescriptionStatic(); |
| |
| //------------------------------------------------------------------ |
| // Constructors and Destructors |
| //------------------------------------------------------------------ |
| ProcessGDBRemote(Target& target, Listener &listener); |
| |
| virtual |
| ~ProcessGDBRemote(); |
| |
| //------------------------------------------------------------------ |
| // Check if a given Process |
| //------------------------------------------------------------------ |
| bool |
| CanDebug (Target &target, bool plugin_specified_by_name) override; |
| |
| CommandObject * |
| GetPluginCommandObject() override; |
| |
| //------------------------------------------------------------------ |
| // Creating a new process, or attaching to an existing one |
| //------------------------------------------------------------------ |
| Error |
| WillLaunch (Module* module) override; |
| |
| Error |
| DoLaunch (Module *exe_module, ProcessLaunchInfo &launch_info) override; |
| |
| void |
| DidLaunch () override; |
| |
| Error |
| WillAttachToProcessWithID (lldb::pid_t pid) override; |
| |
| Error |
| WillAttachToProcessWithName (const char *process_name, bool wait_for_launch) override; |
| |
| Error |
| DoConnectRemote (Stream *strm, const char *remote_url) override; |
| |
| Error |
| WillLaunchOrAttach (); |
| |
| Error |
| DoAttachToProcessWithID (lldb::pid_t pid, const ProcessAttachInfo &attach_info) override; |
| |
| Error |
| DoAttachToProcessWithName (const char *process_name, |
| const ProcessAttachInfo &attach_info) override; |
| |
| void |
| DidAttach (ArchSpec &process_arch) override; |
| |
| //------------------------------------------------------------------ |
| // PluginInterface protocol |
| //------------------------------------------------------------------ |
| ConstString |
| GetPluginName() override; |
| |
| uint32_t |
| GetPluginVersion() override; |
| |
| //------------------------------------------------------------------ |
| // Process Control |
| //------------------------------------------------------------------ |
| Error |
| WillResume () override; |
| |
| Error |
| DoResume () override; |
| |
| Error |
| DoHalt (bool &caused_stop) override; |
| |
| Error |
| DoDetach (bool keep_stopped) override; |
| |
| bool |
| DetachRequiresHalt() override { return true; } |
| |
| Error |
| DoSignal (int signal) override; |
| |
| Error |
| DoDestroy () override; |
| |
| void |
| RefreshStateAfterStop() override; |
| |
| //------------------------------------------------------------------ |
| // Process Queries |
| //------------------------------------------------------------------ |
| bool |
| IsAlive () override; |
| |
| lldb::addr_t |
| GetImageInfoAddress() override; |
| |
| //------------------------------------------------------------------ |
| // Process Memory |
| //------------------------------------------------------------------ |
| size_t |
| DoReadMemory (lldb::addr_t addr, void *buf, size_t size, Error &error) override; |
| |
| size_t |
| DoWriteMemory (lldb::addr_t addr, const void *buf, size_t size, Error &error) override; |
| |
| lldb::addr_t |
| DoAllocateMemory (size_t size, uint32_t permissions, Error &error) override; |
| |
| Error |
| GetMemoryRegionInfo (lldb::addr_t load_addr, MemoryRegionInfo ®ion_info) override; |
| |
| Error |
| DoDeallocateMemory (lldb::addr_t ptr) override; |
| |
| //------------------------------------------------------------------ |
| // Process STDIO |
| //------------------------------------------------------------------ |
| size_t |
| PutSTDIN (const char *buf, size_t buf_size, Error &error) override; |
| |
| //---------------------------------------------------------------------- |
| // Process Breakpoints |
| //---------------------------------------------------------------------- |
| Error |
| EnableBreakpointSite (BreakpointSite *bp_site) override; |
| |
| Error |
| DisableBreakpointSite (BreakpointSite *bp_site) override; |
| |
| //---------------------------------------------------------------------- |
| // Process Watchpoints |
| //---------------------------------------------------------------------- |
| Error |
| EnableWatchpoint (Watchpoint *wp, bool notify = true) override; |
| |
| Error |
| DisableWatchpoint (Watchpoint *wp, bool notify = true) override; |
| |
| Error |
| GetWatchpointSupportInfo (uint32_t &num) override; |
| |
| Error |
| GetWatchpointSupportInfo (uint32_t &num, bool& after) override; |
| |
| bool |
| StartNoticingNewThreads() override; |
| |
| bool |
| StopNoticingNewThreads() override; |
| |
| GDBRemoteCommunicationClient & |
| GetGDBRemote() |
| { |
| return m_gdb_comm; |
| } |
| |
| Error |
| SendEventData(const char *data) override; |
| |
| //---------------------------------------------------------------------- |
| // Override DidExit so we can disconnect from the remote GDB server |
| //---------------------------------------------------------------------- |
| void |
| DidExit () override; |
| |
| void |
| SetUserSpecifiedMaxMemoryTransferSize (uint64_t user_specified_max); |
| |
| bool |
| GetModuleSpec(const FileSpec& module_file_spec, |
| const ArchSpec& arch, |
| ModuleSpec &module_spec) override; |
| |
| size_t |
| LoadModules() override; |
| |
| Error |
| GetFileLoadAddress(const FileSpec& file, bool& is_loaded, lldb::addr_t& load_addr) override; |
| |
| void |
| ModulesDidLoad (ModuleList &module_list) override; |
| |
| StructuredData::ObjectSP |
| GetLoadedDynamicLibrariesInfos (lldb::addr_t image_list_address, lldb::addr_t image_count) override; |
| |
| protected: |
| friend class ThreadGDBRemote; |
| friend class GDBRemoteCommunicationClient; |
| friend class GDBRemoteRegisterContext; |
| |
| class GDBLoadedModuleInfoList; |
| |
| //---------------------------------------------------------------------- |
| // Accessors |
| //---------------------------------------------------------------------- |
| bool |
| IsRunning ( lldb::StateType state ) |
| { |
| return state == lldb::eStateRunning || IsStepping(state); |
| } |
| |
| bool |
| IsStepping ( lldb::StateType state) |
| { |
| return state == lldb::eStateStepping; |
| } |
| bool |
| CanResume ( lldb::StateType state) |
| { |
| return state == lldb::eStateStopped; |
| } |
| |
| bool |
| HasExited (lldb::StateType state) |
| { |
| return state == lldb::eStateExited; |
| } |
| |
| bool |
| ProcessIDIsValid ( ) const; |
| |
| void |
| Clear ( ); |
| |
| Flags & |
| GetFlags () |
| { |
| return m_flags; |
| } |
| |
| const Flags & |
| GetFlags () const |
| { |
| return m_flags; |
| } |
| |
| bool |
| UpdateThreadList (ThreadList &old_thread_list, |
| ThreadList &new_thread_list) override; |
| |
| Error |
| LaunchAndConnectToDebugserver (const ProcessInfo &process_info); |
| |
| void |
| KillDebugserverProcess (); |
| |
| void |
| BuildDynamicRegisterInfo (bool force); |
| |
| void |
| SetLastStopPacket (const StringExtractorGDBRemote &response); |
| |
| bool |
| ParsePythonTargetDefinition(const FileSpec &target_definition_fspec); |
| |
| const lldb::DataBufferSP |
| GetAuxvData() override; |
| |
| StructuredData::ObjectSP |
| GetExtendedInfoForThread (lldb::tid_t tid); |
| |
| void |
| GetMaxMemorySize(); |
| |
| bool |
| CalculateThreadStopInfo (ThreadGDBRemote *thread); |
| |
| size_t |
| UpdateThreadIDsFromStopReplyThreadsValue (std::string &value); |
| |
| //------------------------------------------------------------------ |
| /// Broadcaster event bits definitions. |
| //------------------------------------------------------------------ |
| enum |
| { |
| eBroadcastBitAsyncContinue = (1 << 0), |
| eBroadcastBitAsyncThreadShouldExit = (1 << 1), |
| eBroadcastBitAsyncThreadDidExit = (1 << 2) |
| }; |
| |
| Flags m_flags; // Process specific flags (see eFlags enums) |
| GDBRemoteCommunicationClient m_gdb_comm; |
| std::atomic<lldb::pid_t> m_debugserver_pid; |
| std::vector<StringExtractorGDBRemote> m_stop_packet_stack; // The stop packet stack replaces the last stop packet variable |
| Mutex m_last_stop_packet_mutex; |
| GDBRemoteDynamicRegisterInfo m_register_info; |
| Broadcaster m_async_broadcaster; |
| HostThread m_async_thread; |
| Mutex m_async_thread_state_mutex; |
| typedef std::vector<lldb::tid_t> tid_collection; |
| typedef std::vector< std::pair<lldb::tid_t,int> > tid_sig_collection; |
| typedef std::map<lldb::addr_t, lldb::addr_t> MMapMap; |
| typedef std::map<uint32_t, std::string> ExpeditedRegisterMap; |
| tid_collection m_thread_ids; // Thread IDs for all threads. This list gets updated after stopping |
| StructuredData::ObjectSP m_threads_info_sp; // Stop info for all threads if "jThreadsInfo" packet is supported |
| tid_collection m_continue_c_tids; // 'c' for continue |
| tid_sig_collection m_continue_C_tids; // 'C' for continue with signal |
| tid_collection m_continue_s_tids; // 's' for step |
| tid_sig_collection m_continue_S_tids; // 'S' for step with signal |
| uint64_t m_max_memory_size; // The maximum number of bytes to read/write when reading and writing memory |
| uint64_t m_remote_stub_max_memory_size; // The maximum memory size the remote gdb stub can handle |
| MMapMap m_addr_to_mmap_size; |
| lldb::BreakpointSP m_thread_create_bp_sp; |
| bool m_waiting_for_attach; |
| bool m_destroy_tried_resuming; |
| lldb::CommandObjectSP m_command_sp; |
| int64_t m_breakpoint_pc_offset; |
| lldb::tid_t m_initial_tid; // The inital thread ID, given by stub on attach |
| |
| bool |
| HandleNotifyPacket(StringExtractorGDBRemote &packet); |
| |
| bool |
| StartAsyncThread (); |
| |
| void |
| StopAsyncThread (); |
| |
| static lldb::thread_result_t |
| AsyncThread (void *arg); |
| |
| static bool |
| MonitorDebugserverProcess (void *callback_baton, |
| lldb::pid_t pid, |
| bool exited, |
| int signo, |
| int exit_status); |
| |
| lldb::StateType |
| SetThreadStopInfo (StringExtractor& stop_packet); |
| |
| lldb::StateType |
| SetThreadStopInfo (StructuredData::Dictionary *thread_dict); |
| |
| lldb::ThreadSP |
| SetThreadStopInfo (lldb::tid_t tid, |
| ExpeditedRegisterMap &expedited_register_map, |
| uint8_t signo, |
| const std::string &thread_name, |
| const std::string &reason, |
| const std::string &description, |
| uint32_t exc_type, |
| const std::vector<lldb::addr_t> &exc_data, |
| lldb::addr_t thread_dispatch_qaddr, |
| bool queue_vars_valid, |
| std::string &queue_name, |
| lldb::QueueKind queue_kind, |
| uint64_t queue_serial); |
| |
| void |
| HandleStopReplySequence (); |
| |
| void |
| ClearThreadIDList (); |
| |
| bool |
| UpdateThreadIDList (); |
| |
| void |
| DidLaunchOrAttach (ArchSpec& process_arch); |
| |
| Error |
| ConnectToDebugserver (const char *host_port); |
| |
| const char * |
| GetDispatchQueueNameForThread (lldb::addr_t thread_dispatch_qaddr, |
| std::string &dispatch_queue_name); |
| |
| DynamicLoader * |
| GetDynamicLoader () override; |
| |
| // Query remote GDBServer for register information |
| bool |
| GetGDBServerRegisterInfo (); |
| |
| // Query remote GDBServer for a detailed loaded library list |
| Error |
| GetLoadedModuleList (GDBLoadedModuleInfoList &); |
| |
| lldb::ModuleSP |
| LoadModuleAtAddress (const FileSpec &file, lldb::addr_t base_addr); |
| |
| private: |
| //------------------------------------------------------------------ |
| // For ProcessGDBRemote only |
| //------------------------------------------------------------------ |
| static bool |
| NewThreadNotifyBreakpointHit (void *baton, |
| StoppointCallbackContext *context, |
| lldb::user_id_t break_id, |
| lldb::user_id_t break_loc_id); |
| |
| DISALLOW_COPY_AND_ASSIGN (ProcessGDBRemote); |
| |
| }; |
| |
| } // namespace process_gdb_remote |
| } // namespace lldb_private |
| |
| #endif // liblldb_ProcessGDBRemote_h_ |