2010-06-09 00:52:24 +08:00
|
|
|
//===-- 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>
|
2011-02-12 14:28:37 +08:00
|
|
|
#include <vector>
|
2010-06-09 00:52:24 +08:00
|
|
|
|
|
|
|
// Other libraries and framework includes
|
|
|
|
#include "lldb/Core/ArchSpec.h"
|
|
|
|
#include "lldb/Core/Broadcaster.h"
|
2013-05-11 11:09:05 +08:00
|
|
|
#include "lldb/Core/ConstString.h"
|
2010-06-09 00:52:24 +08:00
|
|
|
#include "lldb/Core/Error.h"
|
|
|
|
#include "lldb/Core/StreamString.h"
|
2010-08-10 07:31:02 +08:00
|
|
|
#include "lldb/Core/StringList.h"
|
2010-06-09 00:52:24 +08:00
|
|
|
#include "lldb/Core/ThreadSafeValue.h"
|
|
|
|
#include "lldb/Target/Process.h"
|
|
|
|
#include "lldb/Target/Thread.h"
|
|
|
|
|
2011-03-22 12:00:09 +08:00
|
|
|
#include "GDBRemoteCommunicationClient.h"
|
2010-07-10 04:39:50 +08:00
|
|
|
#include "Utility/StringExtractor.h"
|
2010-06-09 00:52:24 +08:00
|
|
|
#include "GDBRemoteRegisterContext.h"
|
|
|
|
|
|
|
|
class ThreadGDBRemote;
|
|
|
|
|
|
|
|
class ProcessGDBRemote : public lldb_private::Process
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
// Constructors and Destructors
|
|
|
|
//------------------------------------------------------------------
|
2012-02-09 14:16:32 +08:00
|
|
|
static lldb::ProcessSP
|
|
|
|
CreateInstance (lldb_private::Target& target,
|
|
|
|
lldb_private::Listener &listener,
|
|
|
|
const lldb_private::FileSpec *crash_file_path);
|
2010-06-09 00:52:24 +08:00
|
|
|
|
|
|
|
static void
|
|
|
|
Initialize();
|
|
|
|
|
2013-07-16 06:54:20 +08:00
|
|
|
static void
|
|
|
|
DebuggerInitialize (lldb_private::Debugger &debugger);
|
|
|
|
|
2010-06-09 00:52:24 +08:00
|
|
|
static void
|
|
|
|
Terminate();
|
|
|
|
|
2013-05-11 05:47:16 +08:00
|
|
|
static lldb_private::ConstString
|
2010-06-09 00:52:24 +08:00
|
|
|
GetPluginNameStatic();
|
|
|
|
|
|
|
|
static const char *
|
|
|
|
GetPluginDescriptionStatic();
|
|
|
|
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
// Constructors and Destructors
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
ProcessGDBRemote(lldb_private::Target& target, lldb_private::Listener &listener);
|
|
|
|
|
|
|
|
virtual
|
|
|
|
~ProcessGDBRemote();
|
|
|
|
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
// Check if a given Process
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
virtual bool
|
2011-07-18 04:36:25 +08:00
|
|
|
CanDebug (lldb_private::Target &target,
|
|
|
|
bool plugin_specified_by_name);
|
2010-06-09 00:52:24 +08:00
|
|
|
|
2012-10-13 10:07:45 +08:00
|
|
|
virtual lldb_private::CommandObject *
|
|
|
|
GetPluginCommandObject();
|
2010-08-10 07:31:02 +08:00
|
|
|
|
2010-06-09 00:52:24 +08:00
|
|
|
//------------------------------------------------------------------
|
|
|
|
// Creating a new process, or attaching to an existing one
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
virtual lldb_private::Error
|
|
|
|
WillLaunch (lldb_private::Module* module);
|
|
|
|
|
|
|
|
virtual lldb_private::Error
|
2011-11-04 05:22:33 +08:00
|
|
|
DoLaunch (lldb_private::Module *exe_module,
|
2013-12-10 06:52:50 +08:00
|
|
|
lldb_private::ProcessLaunchInfo &launch_info);
|
2010-06-09 00:52:24 +08:00
|
|
|
|
|
|
|
virtual void
|
|
|
|
DidLaunch ();
|
|
|
|
|
|
|
|
virtual lldb_private::Error
|
2010-11-18 13:57:03 +08:00
|
|
|
WillAttachToProcessWithID (lldb::pid_t pid);
|
2010-06-09 00:52:24 +08:00
|
|
|
|
|
|
|
virtual lldb_private::Error
|
2010-11-18 13:57:03 +08:00
|
|
|
WillAttachToProcessWithName (const char *process_name, bool wait_for_launch);
|
2010-06-09 00:52:24 +08:00
|
|
|
|
2011-02-04 09:58:07 +08:00
|
|
|
virtual lldb_private::Error
|
2012-09-29 12:02:01 +08:00
|
|
|
DoConnectRemote (lldb_private::Stream *strm, const char *remote_url);
|
2011-02-04 09:58:07 +08:00
|
|
|
|
2010-06-09 00:52:24 +08:00
|
|
|
lldb_private::Error
|
|
|
|
WillLaunchOrAttach ();
|
|
|
|
|
|
|
|
virtual lldb_private::Error
|
2010-07-10 04:39:50 +08:00
|
|
|
DoAttachToProcessWithID (lldb::pid_t pid);
|
2010-06-09 00:52:24 +08:00
|
|
|
|
|
|
|
virtual lldb_private::Error
|
2012-02-25 09:07:38 +08:00
|
|
|
DoAttachToProcessWithID (lldb::pid_t pid, const lldb_private::ProcessAttachInfo &attach_info);
|
|
|
|
|
|
|
|
virtual lldb_private::Error
|
|
|
|
DoAttachToProcessWithName (const char *process_name,
|
|
|
|
const lldb_private::ProcessAttachInfo &attach_info);
|
2010-06-09 00:52:24 +08:00
|
|
|
|
|
|
|
virtual void
|
|
|
|
DidAttach ();
|
|
|
|
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
// PluginInterface protocol
|
|
|
|
//------------------------------------------------------------------
|
2013-05-11 05:47:16 +08:00
|
|
|
virtual lldb_private::ConstString
|
2010-06-09 00:52:24 +08:00
|
|
|
GetPluginName();
|
|
|
|
|
|
|
|
virtual uint32_t
|
|
|
|
GetPluginVersion();
|
|
|
|
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
// Process Control
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
virtual lldb_private::Error
|
|
|
|
WillResume ();
|
|
|
|
|
|
|
|
virtual lldb_private::Error
|
|
|
|
DoResume ();
|
|
|
|
|
|
|
|
virtual lldb_private::Error
|
2010-11-17 10:32:00 +08:00
|
|
|
DoHalt (bool &caused_stop);
|
2010-06-09 00:52:24 +08:00
|
|
|
|
|
|
|
virtual lldb_private::Error
|
2013-05-02 08:27:30 +08:00
|
|
|
DoDetach (bool keep_stopped);
|
2013-03-29 09:18:12 +08:00
|
|
|
|
|
|
|
virtual bool
|
|
|
|
DetachRequiresHalt() { return true; }
|
2010-06-09 00:52:24 +08:00
|
|
|
|
|
|
|
virtual lldb_private::Error
|
|
|
|
DoSignal (int signal);
|
|
|
|
|
|
|
|
virtual lldb_private::Error
|
|
|
|
DoDestroy ();
|
|
|
|
|
|
|
|
virtual void
|
|
|
|
RefreshStateAfterStop();
|
|
|
|
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
// Process Queries
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
virtual bool
|
|
|
|
IsAlive ();
|
|
|
|
|
|
|
|
virtual lldb::addr_t
|
|
|
|
GetImageInfoAddress();
|
|
|
|
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
// Process Memory
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
virtual size_t
|
|
|
|
DoReadMemory (lldb::addr_t addr, void *buf, size_t size, lldb_private::Error &error);
|
|
|
|
|
|
|
|
virtual size_t
|
|
|
|
DoWriteMemory (lldb::addr_t addr, const void *buf, size_t size, lldb_private::Error &error);
|
|
|
|
|
|
|
|
virtual lldb::addr_t
|
|
|
|
DoAllocateMemory (size_t size, uint32_t permissions, lldb_private::Error &error);
|
|
|
|
|
2011-11-18 15:03:08 +08:00
|
|
|
virtual lldb_private::Error
|
|
|
|
GetMemoryRegionInfo (lldb::addr_t load_addr,
|
|
|
|
lldb_private::MemoryRegionInfo ®ion_info);
|
|
|
|
|
2010-06-09 00:52:24 +08:00
|
|
|
virtual lldb_private::Error
|
|
|
|
DoDeallocateMemory (lldb::addr_t ptr);
|
|
|
|
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
// Process STDIO
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
virtual size_t
|
|
|
|
PutSTDIN (const char *buf, size_t buf_size, lldb_private::Error &error);
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
// Process Breakpoints
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
virtual lldb_private::Error
|
2013-02-15 10:06:30 +08:00
|
|
|
EnableBreakpointSite (lldb_private::BreakpointSite *bp_site);
|
2010-06-09 00:52:24 +08:00
|
|
|
|
|
|
|
virtual lldb_private::Error
|
2013-02-15 10:06:30 +08:00
|
|
|
DisableBreakpointSite (lldb_private::BreakpointSite *bp_site);
|
2010-06-09 00:52:24 +08:00
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
// Process Watchpoints
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
virtual lldb_private::Error
|
2012-12-18 10:03:49 +08:00
|
|
|
EnableWatchpoint (lldb_private::Watchpoint *wp, bool notify = true);
|
2010-06-09 00:52:24 +08:00
|
|
|
|
|
|
|
virtual lldb_private::Error
|
2012-12-18 10:03:49 +08:00
|
|
|
DisableWatchpoint (lldb_private::Watchpoint *wp, bool notify = true);
|
2010-06-09 00:52:24 +08:00
|
|
|
|
2012-05-24 05:09:52 +08:00
|
|
|
virtual lldb_private::Error
|
|
|
|
GetWatchpointSupportInfo (uint32_t &num);
|
|
|
|
|
2012-07-14 07:18:48 +08:00
|
|
|
virtual lldb_private::Error
|
|
|
|
GetWatchpointSupportInfo (uint32_t &num, bool& after);
|
|
|
|
|
2011-01-22 09:33:44 +08:00
|
|
|
virtual bool
|
|
|
|
StartNoticingNewThreads();
|
|
|
|
|
|
|
|
virtual bool
|
|
|
|
StopNoticingNewThreads();
|
2010-06-09 00:52:24 +08:00
|
|
|
|
2012-04-10 06:46:21 +08:00
|
|
|
GDBRemoteCommunicationClient &
|
|
|
|
GetGDBRemote()
|
|
|
|
{
|
|
|
|
return m_gdb_comm;
|
|
|
|
}
|
2013-11-21 05:07:01 +08:00
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
// Override SetExitStatus so we can disconnect from the remote GDB server
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
virtual bool
|
|
|
|
SetExitStatus (int exit_status, const char *cstr);
|
|
|
|
|
2012-04-10 06:46:21 +08:00
|
|
|
|
2010-06-09 00:52:24 +08:00
|
|
|
protected:
|
|
|
|
friend class ThreadGDBRemote;
|
2011-03-22 12:00:09 +08:00
|
|
|
friend class GDBRemoteCommunicationClient;
|
2010-06-09 00:52:24 +08:00
|
|
|
friend class GDBRemoteRegisterContext;
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
// 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 ( );
|
|
|
|
|
|
|
|
lldb_private::Flags &
|
|
|
|
GetFlags ()
|
|
|
|
{
|
|
|
|
return m_flags;
|
|
|
|
}
|
|
|
|
|
|
|
|
const lldb_private::Flags &
|
|
|
|
GetFlags () const
|
|
|
|
{
|
|
|
|
return m_flags;
|
|
|
|
}
|
|
|
|
|
2012-04-10 08:18:59 +08:00
|
|
|
virtual bool
|
2011-08-22 10:49:39 +08:00
|
|
|
UpdateThreadList (lldb_private::ThreadList &old_thread_list,
|
|
|
|
lldb_private::ThreadList &new_thread_list);
|
2010-06-09 00:52:24 +08:00
|
|
|
|
|
|
|
lldb_private::Error
|
2013-12-05 03:19:12 +08:00
|
|
|
LaunchAndConnectToDebugserver (const lldb_private::ProcessInfo &process_info);
|
2010-06-09 00:52:24 +08:00
|
|
|
|
|
|
|
void
|
|
|
|
KillDebugserverProcess ();
|
|
|
|
|
|
|
|
void
|
2011-01-29 15:10:55 +08:00
|
|
|
BuildDynamicRegisterInfo (bool force);
|
2010-06-09 00:52:24 +08:00
|
|
|
|
2011-12-06 12:51:14 +08:00
|
|
|
void
|
2013-05-22 05:55:59 +08:00
|
|
|
SetLastStopPacket (const StringExtractorGDBRemote &response);
|
2012-09-29 16:03:33 +08:00
|
|
|
|
<rdar://problem/14972424>
When debugging with the GDB remote in LLDB, LLDB uses special packets to discover the
registers on the remote server. When those packets aren't supported, LLDB doesn't
know what the registers look like. This checkin implements a setting that can be used
to specify a python file that contains the registers definitions. The setting is:
(lldb) settings set plugin.process.gdb-remote.target-definition-file /path/to/module.py
Inside module there should be a function:
def get_dynamic_setting(target, setting_name):
This dynamic setting function is handed the "target" which is a SBTarget, and the
"setting_name", which is the name of the dynamic setting to retrieve. For the GDB
remote target definition the setting name is 'gdb-server-target-definition'. The
return value is a dictionary that follows the same format as the OperatingSystem
plugins follow. I have checked in an example file that implements the x86_64 GDB
register set for people to see:
examples/python/x86_64_target_definition.py
This allows LLDB to debug to any archticture that is support and allows users to
define the registers contexts when the discovery packets (qRegisterInfo, qHostInfo)
are not supported by the remote GDB server.
A few benefits of doing this in Python:
1 - The dynamic register context was already supported in the OperatingSystem plug-in
2 - Register contexts can use all of the LLDB enumerations and definitions for things
like lldb::Format, lldb::Encoding, generic register numbers, invalid registers
numbers, etc.
3 - The code that generates the register context can use the program to calculate the
register context contents (like offsets, register numbers, and more)
4 - True dynamic detection could be used where variables and types could be read from
the target program itself in order to determine which registers are available since
the target is passed into the python function.
This is designed to be used instead of XML since it is more dynamic and code flow and
functions can be used to make the dictionary.
llvm-svn: 192646
2013-10-15 08:14:28 +08:00
|
|
|
bool
|
|
|
|
ParsePythonTargetDefinition(const lldb_private::FileSpec &target_definition_fspec);
|
|
|
|
|
|
|
|
bool
|
|
|
|
ParseRegisters(lldb_private::ScriptInterpreterObject *registers_array);
|
|
|
|
|
2010-06-09 00:52:24 +08:00
|
|
|
//------------------------------------------------------------------
|
|
|
|
/// Broadcaster event bits definitions.
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
enum
|
|
|
|
{
|
|
|
|
eBroadcastBitAsyncContinue = (1 << 0),
|
2012-04-13 02:49:31 +08:00
|
|
|
eBroadcastBitAsyncThreadShouldExit = (1 << 1),
|
|
|
|
eBroadcastBitAsyncThreadDidExit = (1 << 2)
|
2010-06-09 00:52:24 +08:00
|
|
|
};
|
|
|
|
|
2012-11-01 09:15:33 +08:00
|
|
|
typedef enum AsyncThreadState
|
|
|
|
{
|
|
|
|
eAsyncThreadNotStarted,
|
|
|
|
eAsyncThreadRunning,
|
|
|
|
eAsyncThreadDone
|
|
|
|
} AsyncThreadState;
|
|
|
|
|
2010-06-09 00:52:24 +08:00
|
|
|
lldb_private::Flags m_flags; // Process specific flags (see eFlags enums)
|
2011-03-22 12:00:09 +08:00
|
|
|
GDBRemoteCommunicationClient m_gdb_comm;
|
2010-06-09 00:52:24 +08:00
|
|
|
lldb::pid_t m_debugserver_pid;
|
2011-06-03 06:22:38 +08:00
|
|
|
StringExtractorGDBRemote m_last_stop_packet;
|
2011-12-06 12:51:14 +08:00
|
|
|
lldb_private::Mutex m_last_stop_packet_mutex;
|
2010-06-09 00:52:24 +08:00
|
|
|
GDBRemoteDynamicRegisterInfo m_register_info;
|
|
|
|
lldb_private::Broadcaster m_async_broadcaster;
|
|
|
|
lldb::thread_t m_async_thread;
|
2012-11-01 09:15:33 +08:00
|
|
|
AsyncThreadState m_async_thread_state;
|
|
|
|
lldb_private::Mutex m_async_thread_state_mutex;
|
2011-02-12 14:28:37 +08:00
|
|
|
typedef std::vector<lldb::tid_t> tid_collection;
|
|
|
|
typedef std::vector< std::pair<lldb::tid_t,int> > tid_sig_collection;
|
2011-05-15 09:25:55 +08:00
|
|
|
typedef std::map<lldb::addr_t, lldb::addr_t> MMapMap;
|
2012-04-10 10:25:43 +08:00
|
|
|
tid_collection m_thread_ids; // Thread IDs for all threads. This list gets updated after stopping
|
2011-02-12 14:28:37 +08:00
|
|
|
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
|
2010-06-09 00:52:24 +08:00
|
|
|
size_t m_max_memory_size; // The maximum number of bytes to read/write when reading and writing memory
|
2011-05-15 09:25:55 +08:00
|
|
|
MMapMap m_addr_to_mmap_size;
|
2012-05-15 10:33:01 +08:00
|
|
|
lldb::BreakpointSP m_thread_create_bp_sp;
|
|
|
|
bool m_waiting_for_attach;
|
2012-07-04 08:35:43 +08:00
|
|
|
bool m_destroy_tried_resuming;
|
2012-10-13 10:07:45 +08:00
|
|
|
lldb::CommandObjectSP m_command_sp;
|
2013-10-18 18:04:33 +08:00
|
|
|
int64_t m_breakpoint_pc_offset;
|
2012-05-15 10:33:01 +08:00
|
|
|
|
2010-06-09 00:52:24 +08:00
|
|
|
bool
|
|
|
|
StartAsyncThread ();
|
|
|
|
|
|
|
|
void
|
|
|
|
StopAsyncThread ();
|
|
|
|
|
2013-08-23 20:44:05 +08:00
|
|
|
static lldb::thread_result_t
|
2010-06-09 00:52:24 +08:00
|
|
|
AsyncThread (void *arg);
|
|
|
|
|
|
|
|
static bool
|
|
|
|
MonitorDebugserverProcess (void *callback_baton,
|
|
|
|
lldb::pid_t pid,
|
2011-11-16 13:37:56 +08:00
|
|
|
bool exited,
|
|
|
|
int signo,
|
|
|
|
int exit_status);
|
2010-06-09 00:52:24 +08:00
|
|
|
|
|
|
|
lldb::StateType
|
|
|
|
SetThreadStopInfo (StringExtractor& stop_packet);
|
|
|
|
|
2012-04-10 10:25:43 +08:00
|
|
|
void
|
|
|
|
ClearThreadIDList ();
|
|
|
|
|
|
|
|
bool
|
|
|
|
UpdateThreadIDList ();
|
|
|
|
|
2010-06-09 00:52:24 +08:00
|
|
|
void
|
|
|
|
DidLaunchOrAttach ();
|
|
|
|
|
|
|
|
lldb_private::Error
|
|
|
|
ConnectToDebugserver (const char *host_port);
|
|
|
|
|
|
|
|
const char *
|
|
|
|
GetDispatchQueueNameForThread (lldb::addr_t thread_dispatch_qaddr,
|
|
|
|
std::string &dispatch_queue_name);
|
|
|
|
|
2012-10-03 09:29:34 +08:00
|
|
|
lldb_private::DynamicLoader *
|
|
|
|
GetDynamicLoader ();
|
|
|
|
|
2010-06-09 00:52:24 +08:00
|
|
|
private:
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
// For ProcessGDBRemote only
|
|
|
|
//------------------------------------------------------------------
|
2011-01-22 09:33:44 +08:00
|
|
|
static bool
|
|
|
|
NewThreadNotifyBreakpointHit (void *baton,
|
|
|
|
lldb_private::StoppointCallbackContext *context,
|
|
|
|
lldb::user_id_t break_id,
|
|
|
|
lldb::user_id_t break_loc_id);
|
|
|
|
|
2010-06-09 00:52:24 +08:00
|
|
|
DISALLOW_COPY_AND_ASSIGN (ProcessGDBRemote);
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif // liblldb_ProcessGDBRemote_h_
|