479 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			479 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C++
		
	
	
	
| //===-- 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 <atomic>
 | |
| #include <map>
 | |
| #include <string>
 | |
| #include <vector>
 | |
| 
 | |
| // Other libraries and framework includes
 | |
| // Project 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:
 | |
|     ProcessGDBRemote(lldb::TargetSP target_sp, Listener &listener);
 | |
| 
 | |
|     ~ProcessGDBRemote() override;
 | |
| 
 | |
|     static lldb::ProcessSP
 | |
|     CreateInstance (lldb::TargetSP target_sp,
 | |
|                     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();
 | |
| 
 | |
|     //------------------------------------------------------------------
 | |
|     // Check if a given Process
 | |
|     //------------------------------------------------------------------
 | |
|     bool
 | |
|     CanDebug (lldb::TargetSP target_sp, 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;
 | |
| 
 | |
|     void
 | |
|     SetUnixSignals(const lldb::UnixSignalsSP &signals_sp);
 | |
| 
 | |
|     //------------------------------------------------------------------
 | |
|     // Process Queries
 | |
|     //------------------------------------------------------------------
 | |
|     bool
 | |
|     IsAlive () override;
 | |
| 
 | |
|     lldb::addr_t
 | |
|     GetImageInfoAddress() override;
 | |
| 
 | |
|     void
 | |
|     WillPublicStop () 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;
 | |
| 
 | |
|     bool
 | |
|     GetHostOSVersion(uint32_t &major,
 | |
|                      uint32_t &minor,
 | |
|                      uint32_t &update) 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;
 | |
| 
 | |
|     //------------------------------------------------------------------
 | |
|     /// 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;
 | |
|     Listener m_async_listener;
 | |
|     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_jstopinfo_sp; // Stop info only for any threads that have valid stop infos
 | |
|     StructuredData::ObjectSP m_jthreadsinfo_sp; // Full stop info, expedited registers and memory 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 initial thread ID, given by stub on attach
 | |
| 
 | |
|     //----------------------------------------------------------------------
 | |
|     // 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);
 | |
| 
 | |
|     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);
 | |
| 
 | |
|     bool
 | |
|     GetThreadStopInfoFromJSON (ThreadGDBRemote *thread, const StructuredData::ObjectSP &thread_infos_sp);
 | |
| 
 | |
|     lldb::ThreadSP
 | |
|     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, bool value_is_offset);
 | |
| 
 | |
| 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_
 |