//===-- 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 #include // 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 m_debugserver_pid; std::vector 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 tid_collection; typedef std::vector< std::pair > tid_sig_collection; typedef std::map MMapMap; typedef std::map 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 &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_