forked from OSchip/llvm-project
Separate monolithic GDBRemoteCommunicationServer class into 4 part
GDBRemoteCommunicationServer: Basic packet handling, handler registration LLDBCommonPacketHandler: Common packet handling for lldb-platform and lldb-gdbserver LLDBPlatformPacketHandler: lldb-platform specific packet handling LLGSPacketHandler: lldb-gdbserver specific packet handling Differential Revision: http://reviews.llvm.org/D7538 llvm-svn: 228823
This commit is contained in:
parent
c4d5ed06cd
commit
e13c2731ba
|
@ -737,6 +737,9 @@
|
|||
4CF3D80C15AF4DC800845BF3 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EDB919B414F6F10D008FF64B /* Security.framework */; };
|
||||
4CF52AF51428291E0051E832 /* SBFileSpecList.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CF52AF41428291E0051E832 /* SBFileSpecList.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
4CF52AF8142829390051E832 /* SBFileSpecList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CF52AF7142829390051E832 /* SBFileSpecList.cpp */; };
|
||||
6D55B2901A8A806200A70529 /* GDBRemoteCommunicationServerCommon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D55B28D1A8A806200A70529 /* GDBRemoteCommunicationServerCommon.cpp */; };
|
||||
6D55B2911A8A806200A70529 /* GDBRemoteCommunicationServerLLGS.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D55B28E1A8A806200A70529 /* GDBRemoteCommunicationServerLLGS.cpp */; };
|
||||
6D55B2921A8A806200A70529 /* GDBRemoteCommunicationServerPlatform.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D55B28F1A8A806200A70529 /* GDBRemoteCommunicationServerPlatform.cpp */; };
|
||||
8C2D6A53197A1EAF006989C9 /* MemoryHistory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8C2D6A52197A1EAF006989C9 /* MemoryHistory.cpp */; };
|
||||
8C2D6A5E197A250F006989C9 /* MemoryHistoryASan.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8C2D6A5A197A1FDC006989C9 /* MemoryHistoryASan.cpp */; };
|
||||
8CCB017E19BA28A80009FD44 /* ThreadCollection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CCB017A19BA283D0009FD44 /* ThreadCollection.cpp */; };
|
||||
|
@ -2348,6 +2351,12 @@
|
|||
69A01E1E1236C5D400C660B5 /* Mutex.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Mutex.cpp; sourceTree = "<group>"; };
|
||||
69A01E1F1236C5D400C660B5 /* Symbols.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Symbols.cpp; sourceTree = "<group>"; };
|
||||
69A01E201236C5D400C660B5 /* TimeValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TimeValue.cpp; sourceTree = "<group>"; };
|
||||
6D55B28D1A8A806200A70529 /* GDBRemoteCommunicationServerCommon.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GDBRemoteCommunicationServerCommon.cpp; sourceTree = "<group>"; };
|
||||
6D55B28E1A8A806200A70529 /* GDBRemoteCommunicationServerLLGS.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GDBRemoteCommunicationServerLLGS.cpp; sourceTree = "<group>"; };
|
||||
6D55B28F1A8A806200A70529 /* GDBRemoteCommunicationServerPlatform.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GDBRemoteCommunicationServerPlatform.cpp; sourceTree = "<group>"; };
|
||||
6D55B2931A8A808400A70529 /* GDBRemoteCommunicationServerCommon.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GDBRemoteCommunicationServerCommon.h; sourceTree = "<group>"; };
|
||||
6D55B2941A8A808400A70529 /* GDBRemoteCommunicationServerLLGS.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GDBRemoteCommunicationServerLLGS.h; sourceTree = "<group>"; };
|
||||
6D55B2951A8A808400A70529 /* GDBRemoteCommunicationServerPlatform.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GDBRemoteCommunicationServerPlatform.h; sourceTree = "<group>"; };
|
||||
8C2D6A52197A1EAF006989C9 /* MemoryHistory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = MemoryHistory.cpp; path = source/Target/MemoryHistory.cpp; sourceTree = "<group>"; };
|
||||
8C2D6A54197A1EBE006989C9 /* MemoryHistory.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = MemoryHistory.h; path = include/lldb/Target/MemoryHistory.h; sourceTree = "<group>"; };
|
||||
8C2D6A5A197A1FDC006989C9 /* MemoryHistoryASan.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MemoryHistoryASan.cpp; sourceTree = "<group>"; };
|
||||
|
@ -4868,6 +4877,12 @@
|
|||
4CEE62F71145F1C70064CF93 /* GDB Remote */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
6D55B2931A8A808400A70529 /* GDBRemoteCommunicationServerCommon.h */,
|
||||
6D55B2941A8A808400A70529 /* GDBRemoteCommunicationServerLLGS.h */,
|
||||
6D55B2951A8A808400A70529 /* GDBRemoteCommunicationServerPlatform.h */,
|
||||
6D55B28D1A8A806200A70529 /* GDBRemoteCommunicationServerCommon.cpp */,
|
||||
6D55B28E1A8A806200A70529 /* GDBRemoteCommunicationServerLLGS.cpp */,
|
||||
6D55B28F1A8A806200A70529 /* GDBRemoteCommunicationServerPlatform.cpp */,
|
||||
2618EE5B1315B29C001D6D71 /* GDBRemoteCommunication.cpp */,
|
||||
2618EE5C1315B29C001D6D71 /* GDBRemoteCommunication.h */,
|
||||
26744EED1338317700EF765A /* GDBRemoteCommunicationClient.cpp */,
|
||||
|
@ -5496,7 +5511,7 @@
|
|||
08FB7793FE84155DC02AAC07 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 0600;
|
||||
LastUpgradeCheck = 0610;
|
||||
TargetAttributes = {
|
||||
2690CD161A6DC0D000E717C8 = {
|
||||
CreatedOnToolsVersion = 6.3;
|
||||
|
@ -5820,6 +5835,7 @@
|
|||
2689001513353DDE00698AC0 /* CommandObjectBreakpointCommand.cpp in Sources */,
|
||||
2689001613353DDE00698AC0 /* CommandObjectCommands.cpp in Sources */,
|
||||
AFEC3362194A8ABA00FF05C6 /* StructuredData.cpp in Sources */,
|
||||
6D55B2901A8A806200A70529 /* GDBRemoteCommunicationServerCommon.cpp in Sources */,
|
||||
26474CAC18D0CB070073DEBA /* RegisterContextFreeBSD_x86_64.cpp in Sources */,
|
||||
2689001713353DDE00698AC0 /* CommandObjectDisassemble.cpp in Sources */,
|
||||
2689001813353DDE00698AC0 /* CommandObjectExpression.cpp in Sources */,
|
||||
|
@ -6241,6 +6257,7 @@
|
|||
260CC65015D0440D002BF2E0 /* OptionValueFormat.cpp in Sources */,
|
||||
260CC65115D0440D002BF2E0 /* OptionValueSInt64.cpp in Sources */,
|
||||
260CC65215D0440D002BF2E0 /* OptionValueString.cpp in Sources */,
|
||||
6D55B2911A8A806200A70529 /* GDBRemoteCommunicationServerLLGS.cpp in Sources */,
|
||||
260CC65315D0440D002BF2E0 /* OptionValueUInt64.cpp in Sources */,
|
||||
260CC65415D0440D002BF2E0 /* OptionValueUUID.cpp in Sources */,
|
||||
94BA8B6D176F8C9B005A91B5 /* Range.cpp in Sources */,
|
||||
|
@ -6251,6 +6268,7 @@
|
|||
2640E19F15DC78FD00F23B50 /* Property.cpp in Sources */,
|
||||
26491E3E15E1DB9F00CBFFC2 /* OptionValueRegex.cpp in Sources */,
|
||||
2697A39315E404B1003E682C /* OptionValueArch.cpp in Sources */,
|
||||
6D55B2921A8A806200A70529 /* GDBRemoteCommunicationServerPlatform.cpp in Sources */,
|
||||
94EA1D5C15E6C9B400D4171A /* PythonDataObjects.cpp in Sources */,
|
||||
94D6A0AC16CEB55F00833B6E /* NSSet.cpp in Sources */,
|
||||
94CD704E16F8DDEA00CF1E42 /* Cocoa.cpp in Sources */,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0600"
|
||||
LastUpgradeVersion = "0610"
|
||||
version = "1.8">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "NO"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0600"
|
||||
LastUpgradeVersion = "0610"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0600"
|
||||
LastUpgradeVersion = "0610"
|
||||
version = "1.8">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "NO"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0600"
|
||||
LastUpgradeVersion = "0610"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0600"
|
||||
LastUpgradeVersion = "0610"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0600"
|
||||
version = "1.3">
|
||||
LastUpgradeVersion = "0610"
|
||||
version = "1.8">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "NO"
|
||||
buildImplicitDependencies = "YES">
|
||||
|
|
|
@ -194,8 +194,8 @@ PlatformRemoteGDBServer::GetFileWithUUID (const FileSpec &platform_file,
|
|||
/// Default Constructor
|
||||
//------------------------------------------------------------------
|
||||
PlatformRemoteGDBServer::PlatformRemoteGDBServer () :
|
||||
Platform(false), // This is a remote platform
|
||||
m_gdb_client(true)
|
||||
Platform (false), // This is a remote platform
|
||||
m_gdb_client ()
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,9 @@ add_lldb_library(lldbPluginProcessGDBRemote
|
|||
GDBRemoteCommunication.cpp
|
||||
GDBRemoteCommunicationClient.cpp
|
||||
GDBRemoteCommunicationServer.cpp
|
||||
GDBRemoteCommunicationServerCommon.cpp
|
||||
GDBRemoteCommunicationServerLLGS.cpp
|
||||
GDBRemoteCommunicationServerPlatform.cpp
|
||||
GDBRemoteRegisterContext.cpp
|
||||
ProcessGDBRemote.cpp
|
||||
ProcessGDBRemoteLog.cpp
|
||||
|
|
|
@ -142,8 +142,7 @@ GDBRemoteCommunication::History::Dump (lldb_private::Log *log) const
|
|||
// GDBRemoteCommunication constructor
|
||||
//----------------------------------------------------------------------
|
||||
GDBRemoteCommunication::GDBRemoteCommunication(const char *comm_name,
|
||||
const char *listener_name,
|
||||
bool is_platform) :
|
||||
const char *listener_name) :
|
||||
Communication(comm_name),
|
||||
#ifdef LLDB_CONFIGURATION_DEBUG
|
||||
m_packet_timeout (1000),
|
||||
|
@ -155,7 +154,6 @@ GDBRemoteCommunication::GDBRemoteCommunication(const char *comm_name,
|
|||
m_private_is_running (false),
|
||||
m_history (512),
|
||||
m_send_acks (true),
|
||||
m_is_platform (is_platform),
|
||||
m_listen_url ()
|
||||
{
|
||||
}
|
||||
|
|
|
@ -63,8 +63,7 @@ public:
|
|||
// Constructors and Destructors
|
||||
//------------------------------------------------------------------
|
||||
GDBRemoteCommunication(const char *comm_name,
|
||||
const char *listener_name,
|
||||
bool is_platform);
|
||||
const char *listener_name);
|
||||
|
||||
virtual
|
||||
~GDBRemoteCommunication();
|
||||
|
|
|
@ -48,8 +48,8 @@ using namespace lldb_private;
|
|||
//----------------------------------------------------------------------
|
||||
// GDBRemoteCommunicationClient constructor
|
||||
//----------------------------------------------------------------------
|
||||
GDBRemoteCommunicationClient::GDBRemoteCommunicationClient(bool is_platform) :
|
||||
GDBRemoteCommunication("gdb-remote.client", "gdb-remote.client.rx_packet", is_platform),
|
||||
GDBRemoteCommunicationClient::GDBRemoteCommunicationClient() :
|
||||
GDBRemoteCommunication("gdb-remote.client", "gdb-remote.client.rx_packet"),
|
||||
m_supports_not_sending_acks (eLazyBoolCalculate),
|
||||
m_supports_thread_suffix (eLazyBoolCalculate),
|
||||
m_supports_threads_in_stop_reply (eLazyBoolCalculate),
|
||||
|
|
|
@ -27,7 +27,7 @@ public:
|
|||
//------------------------------------------------------------------
|
||||
// Constructors and Destructors
|
||||
//------------------------------------------------------------------
|
||||
GDBRemoteCommunicationClient(bool is_platform);
|
||||
GDBRemoteCommunicationClient();
|
||||
|
||||
~GDBRemoteCommunicationClient();
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -12,236 +12,47 @@
|
|||
|
||||
// C Includes
|
||||
// C++ Includes
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <unordered_map>
|
||||
// Other libraries and framework includes
|
||||
// Project includes
|
||||
#include "lldb/lldb-private-forward.h"
|
||||
#include "lldb/Core/Communication.h"
|
||||
#include "lldb/Host/Mutex.h"
|
||||
#include "lldb/Target/Process.h"
|
||||
#include "GDBRemoteCommunication.h"
|
||||
|
||||
#include "lldb/Host/common/NativeProcessProtocol.h"
|
||||
|
||||
class ProcessGDBRemote;
|
||||
class StringExtractorGDBRemote;
|
||||
|
||||
class GDBRemoteCommunicationServer :
|
||||
public GDBRemoteCommunication,
|
||||
public lldb_private::NativeProcessProtocol::NativeDelegate
|
||||
public GDBRemoteCommunication
|
||||
{
|
||||
public:
|
||||
typedef std::map<uint16_t, lldb::pid_t> PortMap;
|
||||
using PortMap = std::map<uint16_t, lldb::pid_t>;
|
||||
using PacketHandler = std::function<PacketResult(StringExtractorGDBRemote &packet,
|
||||
lldb_private::Error &error,
|
||||
bool &interrupt,
|
||||
bool &quit)>;
|
||||
|
||||
enum
|
||||
{
|
||||
eBroadcastBitRunPacketSent = kLoUserBroadcastBit
|
||||
};
|
||||
//------------------------------------------------------------------
|
||||
// Constructors and Destructors
|
||||
//------------------------------------------------------------------
|
||||
GDBRemoteCommunicationServer(bool is_platform);
|
||||
|
||||
GDBRemoteCommunicationServer(bool is_platform,
|
||||
const lldb::PlatformSP& platform_sp,
|
||||
lldb::DebuggerSP& debugger_sp);
|
||||
GDBRemoteCommunicationServer(const char *comm_name,
|
||||
const char *listener_name);
|
||||
|
||||
virtual
|
||||
~GDBRemoteCommunicationServer();
|
||||
|
||||
void RegisterPacketHandler(StringExtractorGDBRemote::ServerPacketType packet_type,
|
||||
PacketHandler handler);
|
||||
|
||||
PacketResult
|
||||
GetPacketAndSendResponse (uint32_t timeout_usec,
|
||||
lldb_private::Error &error,
|
||||
bool &interrupt,
|
||||
bool &quit);
|
||||
|
||||
virtual bool
|
||||
GetThreadSuffixSupported () override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// After connecting, do a little handshake with the client to make sure
|
||||
// we are at least communicating
|
||||
bool
|
||||
HandshakeWithClient (lldb_private::Error *error_ptr);
|
||||
|
||||
// Set both ports to zero to let the platform automatically bind to
|
||||
// a port chosen by the OS.
|
||||
void
|
||||
SetPortMap (PortMap &&port_map)
|
||||
{
|
||||
m_port_map = port_map;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// If we are using a port map where we can only use certain ports,
|
||||
// get the next available port.
|
||||
//
|
||||
// If we are using a port map and we are out of ports, return UINT16_MAX
|
||||
//
|
||||
// If we aren't using a port map, return 0 to indicate we should bind to
|
||||
// port 0 and then figure out which port we used.
|
||||
//----------------------------------------------------------------------
|
||||
uint16_t
|
||||
GetNextAvailablePort ()
|
||||
{
|
||||
if (m_port_map.empty())
|
||||
return 0; // Bind to port zero and get a port, we didn't have any limitations
|
||||
|
||||
for (auto &pair : m_port_map)
|
||||
{
|
||||
if (pair.second == LLDB_INVALID_PROCESS_ID)
|
||||
{
|
||||
pair.second = ~(lldb::pid_t)LLDB_INVALID_PROCESS_ID;
|
||||
return pair.first;
|
||||
}
|
||||
}
|
||||
return UINT16_MAX;
|
||||
}
|
||||
|
||||
bool
|
||||
AssociatePortWithProcess (uint16_t port, lldb::pid_t pid)
|
||||
{
|
||||
PortMap::iterator pos = m_port_map.find(port);
|
||||
if (pos != m_port_map.end())
|
||||
{
|
||||
pos->second = pid;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
FreePort (uint16_t port)
|
||||
{
|
||||
PortMap::iterator pos = m_port_map.find(port);
|
||||
if (pos != m_port_map.end())
|
||||
{
|
||||
pos->second = LLDB_INVALID_PROCESS_ID;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
FreePortForProcess (lldb::pid_t pid)
|
||||
{
|
||||
if (!m_port_map.empty())
|
||||
{
|
||||
for (auto &pair : m_port_map)
|
||||
{
|
||||
if (pair.second == pid)
|
||||
{
|
||||
pair.second = LLDB_INVALID_PROCESS_ID;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
SetPortOffset (uint16_t port_offset)
|
||||
{
|
||||
m_port_offset = port_offset;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Specify the program to launch and its arguments.
|
||||
///
|
||||
/// @param[in] args
|
||||
/// The command line to launch.
|
||||
///
|
||||
/// @param[in] argc
|
||||
/// The number of elements in the args array of cstring pointers.
|
||||
///
|
||||
/// @return
|
||||
/// An Error object indicating the success or failure of making
|
||||
/// the setting.
|
||||
//------------------------------------------------------------------
|
||||
lldb_private::Error
|
||||
SetLaunchArguments (const char *const args[], int argc);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Specify the launch flags for the process.
|
||||
///
|
||||
/// @param[in] launch_flags
|
||||
/// The launch flags to use when launching this process.
|
||||
///
|
||||
/// @return
|
||||
/// An Error object indicating the success or failure of making
|
||||
/// the setting.
|
||||
//------------------------------------------------------------------
|
||||
lldb_private::Error
|
||||
SetLaunchFlags (unsigned int launch_flags);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Launch a process with the current launch settings.
|
||||
///
|
||||
/// This method supports running an lldb-gdbserver or similar
|
||||
/// server in a situation where the startup code has been provided
|
||||
/// with all the information for a child process to be launched.
|
||||
///
|
||||
/// @return
|
||||
/// An Error object indicating the success or failure of the
|
||||
/// launch.
|
||||
//------------------------------------------------------------------
|
||||
lldb_private::Error
|
||||
LaunchProcess ();
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Attach to a process.
|
||||
///
|
||||
/// This method supports attaching llgs to a process accessible via the
|
||||
/// configured Platform.
|
||||
///
|
||||
/// @return
|
||||
/// An Error object indicating the success or failure of the
|
||||
/// attach operation.
|
||||
//------------------------------------------------------------------
|
||||
lldb_private::Error
|
||||
AttachToProcess (lldb::pid_t pid);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// NativeProcessProtocol::NativeDelegate overrides
|
||||
//------------------------------------------------------------------
|
||||
void
|
||||
InitializeDelegate (lldb_private::NativeProcessProtocol *process) override;
|
||||
|
||||
void
|
||||
ProcessStateChanged (lldb_private::NativeProcessProtocol *process, lldb::StateType state) override;
|
||||
|
||||
void
|
||||
DidExec (lldb_private::NativeProcessProtocol *process) override;
|
||||
|
||||
protected:
|
||||
lldb::PlatformSP m_platform_sp;
|
||||
lldb::thread_t m_async_thread;
|
||||
lldb_private::ProcessLaunchInfo m_process_launch_info;
|
||||
lldb_private::Error m_process_launch_error;
|
||||
std::set<lldb::pid_t> m_spawned_pids;
|
||||
lldb_private::Mutex m_spawned_pids_mutex;
|
||||
lldb_private::ProcessInstanceInfoList m_proc_infos;
|
||||
uint32_t m_proc_infos_index;
|
||||
PortMap m_port_map;
|
||||
uint16_t m_port_offset;
|
||||
lldb::tid_t m_current_tid;
|
||||
lldb::tid_t m_continue_tid;
|
||||
lldb_private::Mutex m_debugged_process_mutex;
|
||||
lldb_private::NativeProcessProtocolSP m_debugged_process_sp;
|
||||
lldb::DebuggerSP m_debugger_sp;
|
||||
Communication m_stdio_communication;
|
||||
std::map<StringExtractorGDBRemote::ServerPacketType, PacketHandler> m_packet_handlers;
|
||||
bool m_exit_now; // use in asynchronous handling to indicate process should exit.
|
||||
lldb::StateType m_inferior_prev_state;
|
||||
bool m_thread_suffix_supported;
|
||||
bool m_list_threads_in_stop_reply;
|
||||
lldb::DataBufferSP m_active_auxv_buffer_sp;
|
||||
lldb_private::Mutex m_saved_registers_mutex;
|
||||
std::unordered_map<uint32_t, lldb::DataBufferSP> m_saved_registers_map;
|
||||
uint32_t m_next_saved_registers_id;
|
||||
|
||||
PacketResult
|
||||
SendUnimplementedResponse (const char *packet);
|
||||
|
@ -255,302 +66,7 @@ protected:
|
|||
PacketResult
|
||||
SendOKResponse ();
|
||||
|
||||
PacketResult
|
||||
SendONotification (const char *buffer, uint32_t len);
|
||||
|
||||
PacketResult
|
||||
SendWResponse (lldb_private::NativeProcessProtocol *process);
|
||||
|
||||
PacketResult
|
||||
SendStopReplyPacketForThread (lldb::tid_t tid);
|
||||
|
||||
PacketResult
|
||||
SendStopReasonForState (lldb::StateType process_state, bool flush_on_exit);
|
||||
|
||||
PacketResult
|
||||
Handle_A (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_qLaunchSuccess (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_qHostInfo (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_qLaunchGDBServer (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_qKillSpawnedProcess (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_k (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_qPlatform_mkdir (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_qPlatform_chmod (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_qProcessInfo (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_qProcessInfoPID (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_qfProcessInfo (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_qsProcessInfo (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_qC (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_qUserName (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_qGroupName (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_qSpeedTest (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_QEnvironment (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_QLaunchArch (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_QSetDisableASLR (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_QSetDetachOnError (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_QSetWorkingDir (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_qGetWorkingDir (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_QStartNoAckMode (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_QSetSTDIN (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_QSetSTDOUT (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_QSetSTDERR (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_C (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_c (StringExtractorGDBRemote &packet, bool skip_file_pos_adjustment = false);
|
||||
|
||||
PacketResult
|
||||
Handle_vCont (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_vCont_actions (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_stop_reason (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_vFile_Open (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_vFile_Close (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_vFile_pRead (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_vFile_pWrite (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_vFile_Size (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_vFile_Mode (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_vFile_Exists (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_vFile_symlink (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_vFile_unlink (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_vFile_Stat (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_vFile_MD5 (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_qPlatform_shell (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_qRegisterInfo (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_qfThreadInfo (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_qsThreadInfo (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_p (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_P (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_H (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_I (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_interrupt (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_m (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_M (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_qMemoryRegionInfoSupported (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_qMemoryRegionInfo (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_Z (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_z (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_s (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_qSupported (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_QThreadSuffixSupported (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_QListThreadsInStopReply (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_qXfer_auxv_read (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_QSaveRegisterState (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_QRestoreRegisterState (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_vAttach (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_D (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_qThreadStopInfo (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_qWatchpointSupportInfo (StringExtractorGDBRemote &packet);
|
||||
|
||||
void
|
||||
SetCurrentThreadID (lldb::tid_t tid);
|
||||
|
||||
lldb::tid_t
|
||||
GetCurrentThreadID () const;
|
||||
|
||||
void
|
||||
SetContinueThreadID (lldb::tid_t tid);
|
||||
|
||||
lldb::tid_t
|
||||
GetContinueThreadID () const { return m_continue_tid; }
|
||||
|
||||
lldb_private::Error
|
||||
SetSTDIOFileDescriptor (int fd);
|
||||
|
||||
static void
|
||||
STDIOReadThreadBytesReceived (void *baton, const void *src, size_t src_len);
|
||||
|
||||
private:
|
||||
bool
|
||||
DebugserverProcessReaped (lldb::pid_t pid);
|
||||
|
||||
static bool
|
||||
ReapDebugserverProcess (void *callback_baton,
|
||||
lldb::pid_t pid,
|
||||
bool exited,
|
||||
int signal,
|
||||
int status);
|
||||
|
||||
bool
|
||||
DebuggedProcessReaped (lldb::pid_t pid);
|
||||
|
||||
static bool
|
||||
ReapDebuggedProcess (void *callback_baton,
|
||||
lldb::pid_t pid,
|
||||
bool exited,
|
||||
int signal,
|
||||
int status);
|
||||
|
||||
bool
|
||||
KillSpawnedProcess (lldb::pid_t pid);
|
||||
|
||||
bool
|
||||
IsGdbServer ()
|
||||
{
|
||||
return !m_is_platform;
|
||||
}
|
||||
|
||||
/// Launch an inferior process from lldb-gdbserver
|
||||
lldb_private::Error
|
||||
LaunchProcessForDebugging ();
|
||||
|
||||
/// Launch a process from lldb-platform
|
||||
lldb_private::Error
|
||||
LaunchPlatformProcess ();
|
||||
|
||||
void
|
||||
HandleInferiorState_Exited (lldb_private::NativeProcessProtocol *process);
|
||||
|
||||
void
|
||||
HandleInferiorState_Stopped (lldb_private::NativeProcessProtocol *process);
|
||||
|
||||
void
|
||||
FlushInferiorOutput ();
|
||||
|
||||
lldb_private::NativeThreadProtocolSP
|
||||
GetThreadFromSuffix (StringExtractorGDBRemote &packet);
|
||||
|
||||
uint32_t
|
||||
GetNextSavedRegistersID ();
|
||||
|
||||
void
|
||||
MaybeCloseInferiorTerminalConnection ();
|
||||
|
||||
void
|
||||
ClearProcessSpecificData ();
|
||||
|
||||
bool
|
||||
ShouldRedirectInferiorOutputOverGdbRemote (const lldb_private::ProcessLaunchInfo &launch_info) const;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// For GDBRemoteCommunicationServer only
|
||||
//------------------------------------------------------------------
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,200 @@
|
|||
//===-- GDBRemoteCommunicationServerCommon.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_GDBRemoteCommunicationServerCommon_h_
|
||||
#define liblldb_GDBRemoteCommunicationServerCommon_h_
|
||||
|
||||
// C Includes
|
||||
// C++ Includes
|
||||
#include <set>
|
||||
|
||||
// Other libraries and framework includes
|
||||
#include "lldb/lldb-private-forward.h"
|
||||
#include "lldb/Host/Mutex.h"
|
||||
#include "lldb/Target/Process.h"
|
||||
|
||||
// Project includes
|
||||
#include "GDBRemoteCommunicationServer.h"
|
||||
#include "GDBRemoteCommunicationServerCommon.h"
|
||||
|
||||
class ProcessGDBRemote;
|
||||
class StringExtractorGDBRemote;
|
||||
|
||||
class GDBRemoteCommunicationServerCommon :
|
||||
public GDBRemoteCommunicationServer
|
||||
{
|
||||
public:
|
||||
GDBRemoteCommunicationServerCommon(const char *comm_name, const char *listener_name);
|
||||
|
||||
virtual
|
||||
~GDBRemoteCommunicationServerCommon();
|
||||
|
||||
virtual bool
|
||||
GetThreadSuffixSupported () override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Launch a process with the current launch settings.
|
||||
///
|
||||
/// This method supports running an lldb-gdbserver or similar
|
||||
/// server in a situation where the startup code has been provided
|
||||
/// with all the information for a child process to be launched.
|
||||
///
|
||||
/// @return
|
||||
/// An Error object indicating the success or failure of the
|
||||
/// launch.
|
||||
//------------------------------------------------------------------
|
||||
virtual lldb_private::Error
|
||||
LaunchProcess () = 0;
|
||||
|
||||
protected:
|
||||
std::set<lldb::pid_t> m_spawned_pids;
|
||||
lldb_private::Mutex m_spawned_pids_mutex;
|
||||
lldb_private::ProcessLaunchInfo m_process_launch_info;
|
||||
lldb_private::Error m_process_launch_error;
|
||||
lldb_private::ProcessInstanceInfoList m_proc_infos;
|
||||
uint32_t m_proc_infos_index;
|
||||
bool m_thread_suffix_supported;
|
||||
bool m_list_threads_in_stop_reply;
|
||||
|
||||
PacketResult
|
||||
Handle_A (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_qHostInfo (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_qProcessInfoPID (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_qfProcessInfo (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_qsProcessInfo (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_qUserName (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_qGroupName (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_qSpeedTest (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_qKillSpawnedProcess (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_vFile_Open (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_vFile_Close (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_vFile_pRead (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_vFile_pWrite (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_vFile_Size (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_vFile_Mode (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_vFile_Exists (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_vFile_symlink (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_vFile_unlink (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_vFile_Stat (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_vFile_MD5 (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_qPlatform_shell (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_qPlatform_mkdir (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_qPlatform_chmod (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_qSupported (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_QThreadSuffixSupported (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_QListThreadsInStopReply (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_QSetDetachOnError (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_QStartNoAckMode (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_QSetSTDIN (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_QSetSTDOUT (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_QSetSTDERR (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_qLaunchSuccess (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_QEnvironment (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_QLaunchArch (StringExtractorGDBRemote &packet);
|
||||
|
||||
bool
|
||||
KillSpawnedProcess (lldb::pid_t pid);
|
||||
|
||||
static void
|
||||
CreateProcessInfoResponse (const lldb_private::ProcessInstanceInfo &proc_info,
|
||||
lldb_private::StreamString &response);
|
||||
|
||||
static void
|
||||
CreateProcessInfoResponse_DebugServerStyle (const lldb_private::ProcessInstanceInfo &proc_info,
|
||||
lldb_private::StreamString &response);
|
||||
|
||||
template <typename T>
|
||||
using MemberFunctionPacketHandler = PacketResult (T::*) (StringExtractorGDBRemote& packet);
|
||||
|
||||
template <typename T>
|
||||
void
|
||||
RegisterMemberFunctionHandler(StringExtractorGDBRemote::ServerPacketType packet_type,
|
||||
MemberFunctionPacketHandler<T> handler)
|
||||
{
|
||||
RegisterPacketHandler(packet_type,
|
||||
[this, handler] (StringExtractorGDBRemote packet,
|
||||
lldb_private::Error &error,
|
||||
bool &interrupt,
|
||||
bool &quit)
|
||||
{
|
||||
return (static_cast<T*>(this)->*handler) (packet);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
#endif // liblldb_GDBRemoteCommunicationServerCommon_h_
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,299 @@
|
|||
//===-- GDBRemoteCommunicationServerLLGS.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_GDBRemoteCommunicationServerLLGS_h_
|
||||
#define liblldb_GDBRemoteCommunicationServerLLGS_h_
|
||||
|
||||
// C Includes
|
||||
// C++ Includes
|
||||
#include <unordered_map>
|
||||
|
||||
// Other libraries and framework includes
|
||||
#include "lldb/lldb-private-forward.h"
|
||||
#include "lldb/Core/Communication.h"
|
||||
#include "lldb/Host/Mutex.h"
|
||||
#include "lldb/Host/common/NativeProcessProtocol.h"
|
||||
|
||||
// Project includes
|
||||
#include "GDBRemoteCommunicationServerCommon.h"
|
||||
|
||||
class ProcessGDBRemote;
|
||||
class StringExtractorGDBRemote;
|
||||
|
||||
class GDBRemoteCommunicationServerLLGS :
|
||||
public GDBRemoteCommunicationServerCommon,
|
||||
public lldb_private::NativeProcessProtocol::NativeDelegate
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------
|
||||
// Constructors and Destructors
|
||||
//------------------------------------------------------------------
|
||||
GDBRemoteCommunicationServerLLGS(const lldb::PlatformSP& platform_sp,
|
||||
lldb::DebuggerSP& debugger_sp);
|
||||
|
||||
virtual
|
||||
~GDBRemoteCommunicationServerLLGS();
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Specify the program to launch and its arguments.
|
||||
///
|
||||
/// @param[in] args
|
||||
/// The command line to launch.
|
||||
///
|
||||
/// @param[in] argc
|
||||
/// The number of elements in the args array of cstring pointers.
|
||||
///
|
||||
/// @return
|
||||
/// An Error object indicating the success or failure of making
|
||||
/// the setting.
|
||||
//------------------------------------------------------------------
|
||||
lldb_private::Error
|
||||
SetLaunchArguments (const char *const args[], int argc);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Specify the launch flags for the process.
|
||||
///
|
||||
/// @param[in] launch_flags
|
||||
/// The launch flags to use when launching this process.
|
||||
///
|
||||
/// @return
|
||||
/// An Error object indicating the success or failure of making
|
||||
/// the setting.
|
||||
//------------------------------------------------------------------
|
||||
lldb_private::Error
|
||||
SetLaunchFlags (unsigned int launch_flags);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Launch a process with the current launch settings.
|
||||
///
|
||||
/// This method supports running an lldb-gdbserver or similar
|
||||
/// server in a situation where the startup code has been provided
|
||||
/// with all the information for a child process to be launched.
|
||||
///
|
||||
/// @return
|
||||
/// An Error object indicating the success or failure of the
|
||||
/// launch.
|
||||
//------------------------------------------------------------------
|
||||
lldb_private::Error
|
||||
LaunchProcess () override;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Attach to a process.
|
||||
///
|
||||
/// This method supports attaching llgs to a process accessible via the
|
||||
/// configured Platform.
|
||||
///
|
||||
/// @return
|
||||
/// An Error object indicating the success or failure of the
|
||||
/// attach operation.
|
||||
//------------------------------------------------------------------
|
||||
lldb_private::Error
|
||||
AttachToProcess (lldb::pid_t pid);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// NativeProcessProtocol::NativeDelegate overrides
|
||||
//------------------------------------------------------------------
|
||||
void
|
||||
InitializeDelegate (lldb_private::NativeProcessProtocol *process) override;
|
||||
|
||||
void
|
||||
ProcessStateChanged (lldb_private::NativeProcessProtocol *process, lldb::StateType state) override;
|
||||
|
||||
void
|
||||
DidExec (lldb_private::NativeProcessProtocol *process) override;
|
||||
|
||||
protected:
|
||||
lldb::PlatformSP m_platform_sp;
|
||||
lldb::thread_t m_async_thread;
|
||||
lldb::tid_t m_current_tid;
|
||||
lldb::tid_t m_continue_tid;
|
||||
lldb_private::Mutex m_debugged_process_mutex;
|
||||
lldb_private::NativeProcessProtocolSP m_debugged_process_sp;
|
||||
lldb::DebuggerSP m_debugger_sp;
|
||||
Communication m_stdio_communication;
|
||||
lldb::StateType m_inferior_prev_state;
|
||||
lldb::DataBufferSP m_active_auxv_buffer_sp;
|
||||
lldb_private::Mutex m_saved_registers_mutex;
|
||||
std::unordered_map<uint32_t, lldb::DataBufferSP> m_saved_registers_map;
|
||||
uint32_t m_next_saved_registers_id;
|
||||
|
||||
PacketResult
|
||||
SendONotification (const char *buffer, uint32_t len);
|
||||
|
||||
PacketResult
|
||||
SendWResponse (lldb_private::NativeProcessProtocol *process);
|
||||
|
||||
PacketResult
|
||||
SendStopReplyPacketForThread (lldb::tid_t tid);
|
||||
|
||||
PacketResult
|
||||
SendStopReasonForState (lldb::StateType process_state, bool flush_on_exit);
|
||||
|
||||
PacketResult
|
||||
Handle_k (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_qProcessInfo (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_qC (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_QSetDisableASLR (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_QSetWorkingDir (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_qGetWorkingDir (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_C (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_c (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_vCont (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_vCont_actions (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_stop_reason (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_qRegisterInfo (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_qfThreadInfo (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_qsThreadInfo (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_p (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_P (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_H (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_I (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_interrupt (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_m (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_M (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_qMemoryRegionInfoSupported (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_qMemoryRegionInfo (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_Z (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_z (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_s (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_qXfer_auxv_read (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_QSaveRegisterState (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_QRestoreRegisterState (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_vAttach (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_D (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_qThreadStopInfo (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_qWatchpointSupportInfo (StringExtractorGDBRemote &packet);
|
||||
|
||||
void
|
||||
SetCurrentThreadID (lldb::tid_t tid);
|
||||
|
||||
lldb::tid_t
|
||||
GetCurrentThreadID () const;
|
||||
|
||||
void
|
||||
SetContinueThreadID (lldb::tid_t tid);
|
||||
|
||||
lldb::tid_t
|
||||
GetContinueThreadID () const { return m_continue_tid; }
|
||||
|
||||
lldb_private::Error
|
||||
SetSTDIOFileDescriptor (int fd);
|
||||
|
||||
static void
|
||||
STDIOReadThreadBytesReceived (void *baton, const void *src, size_t src_len);
|
||||
|
||||
private:
|
||||
bool
|
||||
DebuggedProcessReaped (lldb::pid_t pid);
|
||||
|
||||
static bool
|
||||
ReapDebuggedProcess (void *callback_baton,
|
||||
lldb::pid_t pid,
|
||||
bool exited,
|
||||
int signal,
|
||||
int status);
|
||||
|
||||
void
|
||||
HandleInferiorState_Exited (lldb_private::NativeProcessProtocol *process);
|
||||
|
||||
void
|
||||
HandleInferiorState_Stopped (lldb_private::NativeProcessProtocol *process);
|
||||
|
||||
void
|
||||
FlushInferiorOutput ();
|
||||
|
||||
lldb_private::NativeThreadProtocolSP
|
||||
GetThreadFromSuffix (StringExtractorGDBRemote &packet);
|
||||
|
||||
uint32_t
|
||||
GetNextSavedRegistersID ();
|
||||
|
||||
void
|
||||
MaybeCloseInferiorTerminalConnection ();
|
||||
|
||||
void
|
||||
ClearProcessSpecificData ();
|
||||
|
||||
bool
|
||||
ShouldRedirectInferiorOutputOverGdbRemote (const lldb_private::ProcessLaunchInfo &launch_info) const;
|
||||
|
||||
void
|
||||
RegisterPacketHandlers ();
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// For GDBRemoteCommunicationServerLLGS only
|
||||
//------------------------------------------------------------------
|
||||
DISALLOW_COPY_AND_ASSIGN (GDBRemoteCommunicationServerLLGS);
|
||||
};
|
||||
|
||||
#endif // liblldb_GDBRemoteCommunicationServerLLGS_h_
|
|
@ -0,0 +1,380 @@
|
|||
//===-- GDBRemoteCommunicationServerPlatform.cpp ----------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "GDBRemoteCommunicationServerPlatform.h"
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
// C Includes
|
||||
// C++ Includes
|
||||
#include <cstring>
|
||||
#include <chrono>
|
||||
|
||||
// Other libraries and framework includes
|
||||
#include "lldb/Core/Log.h"
|
||||
#include "lldb/Core/StreamString.h"
|
||||
#include "lldb/Host/Config.h"
|
||||
#include "lldb/Host/ConnectionFileDescriptor.h"
|
||||
#include "lldb/Host/Host.h"
|
||||
#include "lldb/Host/StringConvert.h"
|
||||
#include "lldb/Target/FileAction.h"
|
||||
#include "lldb/Target/Platform.h"
|
||||
#include "lldb/Target/Process.h"
|
||||
|
||||
// Project includes
|
||||
#include "Utility/StringExtractorGDBRemote.h"
|
||||
#include "Utility/UriParser.h"
|
||||
|
||||
using namespace lldb;
|
||||
using namespace lldb_private;
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// GDBRemoteCommunicationServerPlatform constructor
|
||||
//----------------------------------------------------------------------
|
||||
GDBRemoteCommunicationServerPlatform::GDBRemoteCommunicationServerPlatform() :
|
||||
GDBRemoteCommunicationServerCommon ("gdb-remote.server", "gdb-remote.server.rx_packet"),
|
||||
m_platform_sp (Platform::GetHostPlatform ()),
|
||||
m_port_map (),
|
||||
m_port_offset(0)
|
||||
{
|
||||
RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qC,
|
||||
&GDBRemoteCommunicationServerPlatform::Handle_qC);
|
||||
RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qGetWorkingDir,
|
||||
&GDBRemoteCommunicationServerPlatform::Handle_qGetWorkingDir);
|
||||
RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qLaunchGDBServer,
|
||||
&GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer);
|
||||
RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qProcessInfo,
|
||||
&GDBRemoteCommunicationServerPlatform::Handle_qProcessInfo);
|
||||
RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_QSetWorkingDir,
|
||||
&GDBRemoteCommunicationServerPlatform::Handle_QSetWorkingDir);
|
||||
|
||||
RegisterPacketHandler(StringExtractorGDBRemote::eServerPacketType_interrupt,
|
||||
[this](StringExtractorGDBRemote packet,
|
||||
Error &error,
|
||||
bool &interrupt,
|
||||
bool &quit)
|
||||
{
|
||||
error.SetErrorString("interrupt received");
|
||||
interrupt = true;
|
||||
return PacketResult::Success;
|
||||
});
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Destructor
|
||||
//----------------------------------------------------------------------
|
||||
GDBRemoteCommunicationServerPlatform::~GDBRemoteCommunicationServerPlatform()
|
||||
{
|
||||
}
|
||||
|
||||
GDBRemoteCommunication::PacketResult
|
||||
GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer (StringExtractorGDBRemote &packet)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return SendErrorResponse(9);
|
||||
#else
|
||||
// Spawn a local debugserver as a platform so we can then attach or launch
|
||||
// a process...
|
||||
|
||||
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
|
||||
if (log)
|
||||
log->Printf ("LLGSPacketHandler::%s() called", __FUNCTION__);
|
||||
|
||||
// Sleep and wait a bit for debugserver to start to listen...
|
||||
ConnectionFileDescriptor file_conn;
|
||||
std::string hostname;
|
||||
// TODO: /tmp/ should not be hardcoded. User might want to override /tmp
|
||||
// with the TMPDIR environment variable
|
||||
packet.SetFilePos(::strlen ("qLaunchLLGSPacketHandler;"));
|
||||
std::string name;
|
||||
std::string value;
|
||||
uint16_t port = UINT16_MAX;
|
||||
while (packet.GetNameColonValue(name, value))
|
||||
{
|
||||
if (name.compare ("host") == 0)
|
||||
hostname.swap(value);
|
||||
else if (name.compare ("port") == 0)
|
||||
port = StringConvert::ToUInt32(value.c_str(), 0, 0);
|
||||
}
|
||||
if (port == UINT16_MAX)
|
||||
port = GetNextAvailablePort();
|
||||
|
||||
// Spawn a new thread to accept the port that gets bound after
|
||||
// binding to port 0 (zero).
|
||||
|
||||
// ignore the hostname send from the remote end, just use the ip address
|
||||
// that we're currently communicating with as the hostname
|
||||
|
||||
// Spawn a debugserver and try to get the port it listens to.
|
||||
ProcessLaunchInfo debugserver_launch_info;
|
||||
if (hostname.empty())
|
||||
hostname = "127.0.0.1";
|
||||
if (log)
|
||||
log->Printf("Launching debugserver with: %s:%u...\n", hostname.c_str(), port);
|
||||
|
||||
// Do not run in a new session so that it can not linger after the
|
||||
// platform closes.
|
||||
debugserver_launch_info.SetLaunchInSeparateProcessGroup(false);
|
||||
debugserver_launch_info.SetMonitorProcessCallback(ReapDebugserverProcess, this, false);
|
||||
|
||||
std::string platform_scheme;
|
||||
std::string platform_ip;
|
||||
int platform_port;
|
||||
std::string platform_path;
|
||||
bool ok = UriParser::Parse(GetConnection()->GetURI().c_str(), platform_scheme, platform_ip, platform_port, platform_path);
|
||||
assert(ok);
|
||||
Error error = StartDebugserverProcess (
|
||||
platform_ip.c_str(),
|
||||
port,
|
||||
debugserver_launch_info,
|
||||
port);
|
||||
|
||||
lldb::pid_t debugserver_pid = debugserver_launch_info.GetProcessID();
|
||||
|
||||
|
||||
if (debugserver_pid != LLDB_INVALID_PROCESS_ID)
|
||||
{
|
||||
Mutex::Locker locker (m_spawned_pids_mutex);
|
||||
m_spawned_pids.insert(debugserver_pid);
|
||||
if (port > 0)
|
||||
AssociatePortWithProcess(port, debugserver_pid);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (port > 0)
|
||||
FreePort (port);
|
||||
}
|
||||
|
||||
if (error.Success())
|
||||
{
|
||||
if (log)
|
||||
log->Printf ("LLGSPacketHandler::%s() debugserver launched successfully as pid %" PRIu64, __FUNCTION__, debugserver_pid);
|
||||
|
||||
char response[256];
|
||||
const int response_len = ::snprintf (response, sizeof(response), "pid:%" PRIu64 ";port:%u;", debugserver_pid, port + m_port_offset);
|
||||
assert (response_len < (int)sizeof(response));
|
||||
PacketResult packet_result = SendPacketNoLock (response, response_len);
|
||||
|
||||
if (packet_result != PacketResult::Success)
|
||||
{
|
||||
if (debugserver_pid != LLDB_INVALID_PROCESS_ID)
|
||||
::kill (debugserver_pid, SIGINT);
|
||||
}
|
||||
return packet_result;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (log)
|
||||
log->Printf ("LLGSPacketHandler::%s() debugserver launch failed: %s", __FUNCTION__, error.AsCString ());
|
||||
}
|
||||
return SendErrorResponse (9);
|
||||
#endif
|
||||
}
|
||||
|
||||
GDBRemoteCommunication::PacketResult
|
||||
GDBRemoteCommunicationServerPlatform::Handle_qProcessInfo (StringExtractorGDBRemote &packet)
|
||||
{
|
||||
lldb::pid_t pid = m_process_launch_info.GetProcessID ();
|
||||
m_process_launch_info.Clear ();
|
||||
|
||||
if (pid == LLDB_INVALID_PROCESS_ID)
|
||||
return SendErrorResponse (1);
|
||||
|
||||
ProcessInstanceInfo proc_info;
|
||||
if (!Host::GetProcessInfo (pid, proc_info))
|
||||
return SendErrorResponse (1);
|
||||
|
||||
StreamString response;
|
||||
CreateProcessInfoResponse_DebugServerStyle(proc_info, response);
|
||||
return SendPacketNoLock (response.GetData (), response.GetSize ());
|
||||
}
|
||||
|
||||
GDBRemoteCommunication::PacketResult
|
||||
GDBRemoteCommunicationServerPlatform::Handle_qGetWorkingDir (StringExtractorGDBRemote &packet)
|
||||
{
|
||||
// If this packet is sent to a platform, then change the current working directory
|
||||
|
||||
char cwd[PATH_MAX];
|
||||
if (getcwd(cwd, sizeof(cwd)) == NULL)
|
||||
return SendErrorResponse(errno);
|
||||
|
||||
StreamString response;
|
||||
response.PutBytesAsRawHex8(cwd, strlen(cwd));
|
||||
return SendPacketNoLock(response.GetData(), response.GetSize());
|
||||
}
|
||||
|
||||
GDBRemoteCommunication::PacketResult
|
||||
GDBRemoteCommunicationServerPlatform::Handle_QSetWorkingDir (StringExtractorGDBRemote &packet)
|
||||
{
|
||||
packet.SetFilePos (::strlen ("QSetWorkingDir:"));
|
||||
std::string path;
|
||||
packet.GetHexByteString (path);
|
||||
|
||||
#ifdef _WIN32
|
||||
// Not implemented on Windows
|
||||
return SendUnimplementedResponse ("LLGSPacketHandler::Handle_QSetWorkingDir unimplemented");
|
||||
#else
|
||||
// If this packet is sent to a platform, then change the current working directory
|
||||
if (::chdir(path.c_str()) != 0)
|
||||
return SendErrorResponse (errno);
|
||||
return SendOKResponse ();
|
||||
#endif
|
||||
}
|
||||
|
||||
GDBRemoteCommunication::PacketResult
|
||||
GDBRemoteCommunicationServerPlatform::Handle_qC (StringExtractorGDBRemote &packet)
|
||||
{
|
||||
// NOTE: lldb should now be using qProcessInfo for process IDs. This path here
|
||||
// should not be used. It is reporting process id instead of thread id. The
|
||||
// correct answer doesn't seem to make much sense for lldb-platform.
|
||||
// CONSIDER: flip to "unsupported".
|
||||
lldb::pid_t pid = m_process_launch_info.GetProcessID();
|
||||
|
||||
StreamString response;
|
||||
response.Printf("QC%" PRIx64, pid);
|
||||
|
||||
// If we launch a process and this GDB server is acting as a platform,
|
||||
// then we need to clear the process launch state so we can start
|
||||
// launching another process. In order to launch a process a bunch or
|
||||
// packets need to be sent: environment packets, working directory,
|
||||
// disable ASLR, and many more settings. When we launch a process we
|
||||
// then need to know when to clear this information. Currently we are
|
||||
// selecting the 'qC' packet as that packet which seems to make the most
|
||||
// sense.
|
||||
if (pid != LLDB_INVALID_PROCESS_ID)
|
||||
{
|
||||
m_process_launch_info.Clear();
|
||||
}
|
||||
|
||||
return SendPacketNoLock (response.GetData(), response.GetSize());
|
||||
}
|
||||
|
||||
bool
|
||||
GDBRemoteCommunicationServerPlatform::DebugserverProcessReaped (lldb::pid_t pid)
|
||||
{
|
||||
Mutex::Locker locker (m_spawned_pids_mutex);
|
||||
FreePortForProcess(pid);
|
||||
return m_spawned_pids.erase(pid) > 0;
|
||||
}
|
||||
|
||||
bool
|
||||
GDBRemoteCommunicationServerPlatform::ReapDebugserverProcess (void *callback_baton,
|
||||
lldb::pid_t pid,
|
||||
bool exited,
|
||||
int signal, // Zero for no signal
|
||||
int status) // Exit value of process if signal is zero
|
||||
{
|
||||
GDBRemoteCommunicationServerPlatform *server = (GDBRemoteCommunicationServerPlatform *)callback_baton;
|
||||
server->DebugserverProcessReaped (pid);
|
||||
return true;
|
||||
}
|
||||
|
||||
lldb_private::Error
|
||||
GDBRemoteCommunicationServerPlatform::LaunchProcess ()
|
||||
{
|
||||
if (!m_process_launch_info.GetArguments ().GetArgumentCount ())
|
||||
return lldb_private::Error ("%s: no process command line specified to launch", __FUNCTION__);
|
||||
|
||||
// specify the process monitor if not already set. This should
|
||||
// generally be what happens since we need to reap started
|
||||
// processes.
|
||||
if (!m_process_launch_info.GetMonitorProcessCallback ())
|
||||
m_process_launch_info.SetMonitorProcessCallback(ReapDebugserverProcess, this, false);
|
||||
|
||||
lldb_private::Error error = m_platform_sp->LaunchProcess (m_process_launch_info);
|
||||
if (!error.Success ())
|
||||
{
|
||||
fprintf (stderr, "%s: failed to launch executable %s", __FUNCTION__, m_process_launch_info.GetArguments ().GetArgumentAtIndex (0));
|
||||
return error;
|
||||
}
|
||||
|
||||
printf ("Launched '%s' as process %" PRIu64 "...\n", m_process_launch_info.GetArguments ().GetArgumentAtIndex (0), m_process_launch_info.GetProcessID());
|
||||
|
||||
// add to list of spawned processes. On an lldb-gdbserver, we
|
||||
// would expect there to be only one.
|
||||
const auto pid = m_process_launch_info.GetProcessID();
|
||||
if (pid != LLDB_INVALID_PROCESS_ID)
|
||||
{
|
||||
// add to spawned pids
|
||||
Mutex::Locker locker (m_spawned_pids_mutex);
|
||||
m_spawned_pids.insert(pid);
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
void
|
||||
GDBRemoteCommunicationServerPlatform::SetPortMap (PortMap &&port_map)
|
||||
{
|
||||
m_port_map = port_map;
|
||||
}
|
||||
|
||||
uint16_t
|
||||
GDBRemoteCommunicationServerPlatform::GetNextAvailablePort ()
|
||||
{
|
||||
if (m_port_map.empty())
|
||||
return 0; // Bind to port zero and get a port, we didn't have any limitations
|
||||
|
||||
for (auto &pair : m_port_map)
|
||||
{
|
||||
if (pair.second == LLDB_INVALID_PROCESS_ID)
|
||||
{
|
||||
pair.second = ~(lldb::pid_t)LLDB_INVALID_PROCESS_ID;
|
||||
return pair.first;
|
||||
}
|
||||
}
|
||||
return UINT16_MAX;
|
||||
}
|
||||
|
||||
bool
|
||||
GDBRemoteCommunicationServerPlatform::AssociatePortWithProcess (uint16_t port, lldb::pid_t pid)
|
||||
{
|
||||
PortMap::iterator pos = m_port_map.find(port);
|
||||
if (pos != m_port_map.end())
|
||||
{
|
||||
pos->second = pid;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
GDBRemoteCommunicationServerPlatform::FreePort (uint16_t port)
|
||||
{
|
||||
PortMap::iterator pos = m_port_map.find(port);
|
||||
if (pos != m_port_map.end())
|
||||
{
|
||||
pos->second = LLDB_INVALID_PROCESS_ID;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
GDBRemoteCommunicationServerPlatform::FreePortForProcess (lldb::pid_t pid)
|
||||
{
|
||||
if (!m_port_map.empty())
|
||||
{
|
||||
for (auto &pair : m_port_map)
|
||||
{
|
||||
if (pair.second == pid)
|
||||
{
|
||||
pair.second = LLDB_INVALID_PROCESS_ID;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
GDBRemoteCommunicationServerPlatform::SetPortOffset (uint16_t port_offset)
|
||||
{
|
||||
m_port_offset = port_offset;
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
//===-- GDBRemoteCommunicationServerPlatform.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_GDBRemoteCommunicationServerPlatform_h_
|
||||
#define liblldb_GDBRemoteCommunicationServerPlatform_h_
|
||||
|
||||
#include "GDBRemoteCommunicationServerCommon.h"
|
||||
|
||||
class GDBRemoteCommunicationServerPlatform :
|
||||
public GDBRemoteCommunicationServerCommon
|
||||
{
|
||||
public:
|
||||
typedef std::map<uint16_t, lldb::pid_t> PortMap;
|
||||
|
||||
GDBRemoteCommunicationServerPlatform();
|
||||
|
||||
virtual
|
||||
~GDBRemoteCommunicationServerPlatform();
|
||||
|
||||
lldb_private::Error
|
||||
LaunchProcess () override;
|
||||
|
||||
// Set both ports to zero to let the platform automatically bind to
|
||||
// a port chosen by the OS.
|
||||
void
|
||||
SetPortMap (PortMap &&port_map);
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// If we are using a port map where we can only use certain ports,
|
||||
// get the next available port.
|
||||
//
|
||||
// If we are using a port map and we are out of ports, return UINT16_MAX
|
||||
//
|
||||
// If we aren't using a port map, return 0 to indicate we should bind to
|
||||
// port 0 and then figure out which port we used.
|
||||
//----------------------------------------------------------------------
|
||||
uint16_t
|
||||
GetNextAvailablePort ();
|
||||
|
||||
bool
|
||||
AssociatePortWithProcess (uint16_t port, lldb::pid_t pid);
|
||||
|
||||
bool
|
||||
FreePort (uint16_t port);
|
||||
|
||||
bool
|
||||
FreePortForProcess (lldb::pid_t pid);
|
||||
|
||||
void
|
||||
SetPortOffset (uint16_t port_offset);
|
||||
|
||||
protected:
|
||||
lldb::PlatformSP m_platform_sp;
|
||||
|
||||
PortMap m_port_map;
|
||||
uint16_t m_port_offset;
|
||||
|
||||
PacketResult
|
||||
Handle_qLaunchGDBServer (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_qProcessInfo (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_qGetWorkingDir (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_QSetWorkingDir (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_qC (StringExtractorGDBRemote &packet);
|
||||
|
||||
private:
|
||||
bool
|
||||
DebugserverProcessReaped (lldb::pid_t pid);
|
||||
|
||||
static bool
|
||||
ReapDebugserverProcess (void *callback_baton,
|
||||
lldb::pid_t pid,
|
||||
bool exited,
|
||||
int signal,
|
||||
int status);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// For GDBRemoteCommunicationServerPlatform only
|
||||
//------------------------------------------------------------------
|
||||
DISALLOW_COPY_AND_ASSIGN (GDBRemoteCommunicationServerPlatform);
|
||||
};
|
||||
|
||||
#endif // liblldb_GDBRemoteCommunicationServerPlatform_h_
|
|
@ -268,7 +268,7 @@ ProcessGDBRemote::CanDebug (Target &target, bool plugin_specified_by_name)
|
|||
ProcessGDBRemote::ProcessGDBRemote(Target& target, Listener &listener) :
|
||||
Process (target, listener),
|
||||
m_flags (0),
|
||||
m_gdb_comm(false),
|
||||
m_gdb_comm (),
|
||||
m_debugserver_pid (LLDB_INVALID_PROCESS_ID),
|
||||
m_last_stop_packet (),
|
||||
m_last_stop_packet_mutex (Mutex::eMutexTypeNormal),
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0600"
|
||||
LastUpgradeVersion = "0610"
|
||||
version = "1.8">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "NO"
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
#include "lldb/Host/ThreadLauncher.h"
|
||||
#include "lldb/Interpreter/CommandInterpreter.h"
|
||||
#include "lldb/Interpreter/CommandReturnObject.h"
|
||||
#include "Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h"
|
||||
#include "Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h"
|
||||
#include "Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h"
|
||||
|
||||
#ifndef LLGS_PROGRAM_NAME
|
||||
|
@ -203,7 +203,7 @@ setup_platform (const std::string &platform_name)
|
|||
}
|
||||
|
||||
void
|
||||
handle_attach_to_pid (GDBRemoteCommunicationServer &gdb_server, lldb::pid_t pid)
|
||||
handle_attach_to_pid (GDBRemoteCommunicationServerLLGS &gdb_server, lldb::pid_t pid)
|
||||
{
|
||||
Error error = gdb_server.AttachToProcess (pid);
|
||||
if (error.Fail ())
|
||||
|
@ -214,13 +214,13 @@ handle_attach_to_pid (GDBRemoteCommunicationServer &gdb_server, lldb::pid_t pid)
|
|||
}
|
||||
|
||||
void
|
||||
handle_attach_to_process_name (GDBRemoteCommunicationServer &gdb_server, const std::string &process_name)
|
||||
handle_attach_to_process_name (GDBRemoteCommunicationServerLLGS &gdb_server, const std::string &process_name)
|
||||
{
|
||||
// FIXME implement.
|
||||
}
|
||||
|
||||
void
|
||||
handle_attach (GDBRemoteCommunicationServer &gdb_server, const std::string &attach_target)
|
||||
handle_attach (GDBRemoteCommunicationServerLLGS &gdb_server, const std::string &attach_target)
|
||||
{
|
||||
assert (!attach_target.empty () && "attach_target cannot be empty");
|
||||
|
||||
|
@ -236,7 +236,7 @@ handle_attach (GDBRemoteCommunicationServer &gdb_server, const std::string &atta
|
|||
}
|
||||
|
||||
void
|
||||
handle_launch (GDBRemoteCommunicationServer &gdb_server, int argc, const char *const argv[])
|
||||
handle_launch (GDBRemoteCommunicationServerLLGS &gdb_server, int argc, const char *const argv[])
|
||||
{
|
||||
Error error;
|
||||
error = gdb_server.SetLaunchArguments (argv, argc);
|
||||
|
@ -326,7 +326,7 @@ writePortToPipe (const char *const named_pipe_path, const uint16_t port)
|
|||
}
|
||||
|
||||
void
|
||||
ConnectToRemote (GDBRemoteCommunicationServer &gdb_server, bool reverse_connect, const char *const host_and_port, const char *const progname, const char *const named_pipe_path)
|
||||
ConnectToRemote (GDBRemoteCommunicationServerLLGS &gdb_server, bool reverse_connect, const char *const host_and_port, const char *const progname, const char *const named_pipe_path)
|
||||
{
|
||||
Error error;
|
||||
|
||||
|
@ -663,11 +663,10 @@ main (int argc, char *argv[])
|
|||
// Run any commands requested.
|
||||
run_lldb_commands (debugger_sp, lldb_commands);
|
||||
|
||||
// Setup the platform that GDBRemoteCommunicationServer will use.
|
||||
// Setup the platform that GDBRemoteCommunicationServerLLGS will use.
|
||||
lldb::PlatformSP platform_sp = setup_platform (platform_name);
|
||||
|
||||
const bool is_platform = false;
|
||||
GDBRemoteCommunicationServer gdb_server (is_platform, platform_sp, debugger_sp);
|
||||
GDBRemoteCommunicationServerLLGS gdb_server (platform_sp, debugger_sp);
|
||||
|
||||
const char *const host_and_port = argv[0];
|
||||
argc -= 1;
|
||||
|
|
|
@ -33,8 +33,9 @@
|
|||
#include "lldb/Host/OptionParser.h"
|
||||
#include "lldb/Interpreter/CommandInterpreter.h"
|
||||
#include "lldb/Interpreter/CommandReturnObject.h"
|
||||
#include "Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h"
|
||||
#include "Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h"
|
||||
#include "Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h"
|
||||
|
||||
using namespace lldb;
|
||||
using namespace lldb_private;
|
||||
|
||||
|
@ -115,7 +116,7 @@ main (int argc, char *argv[])
|
|||
debugger_sp->SetOutputFileHandle(stdout, false);
|
||||
debugger_sp->SetErrorFileHandle(stderr, false);
|
||||
|
||||
GDBRemoteCommunicationServer::PortMap gdbserver_portmap;
|
||||
GDBRemoteCommunicationServerPlatform::PortMap gdbserver_portmap;
|
||||
int min_gdbserver_port = 0;
|
||||
int max_gdbserver_port = 0;
|
||||
uint16_t port_offset = 0;
|
||||
|
@ -246,14 +247,14 @@ main (int argc, char *argv[])
|
|||
|
||||
|
||||
do {
|
||||
GDBRemoteCommunicationServer gdb_server (true);
|
||||
GDBRemoteCommunicationServerPlatform platform;
|
||||
|
||||
if (port_offset > 0)
|
||||
gdb_server.SetPortOffset(port_offset);
|
||||
platform.SetPortOffset(port_offset);
|
||||
|
||||
if (!gdbserver_portmap.empty())
|
||||
{
|
||||
gdb_server.SetPortMap(std::move(gdbserver_portmap));
|
||||
platform.SetPortMap(std::move(gdbserver_portmap));
|
||||
}
|
||||
|
||||
if (!listen_host_port.empty())
|
||||
|
@ -268,7 +269,7 @@ main (int argc, char *argv[])
|
|||
if (conn_ap->Connect(connect_url.c_str(), &error) == eConnectionStatusSuccess)
|
||||
{
|
||||
printf ("Connection established.\n");
|
||||
gdb_server.SetConnection (conn_ap.release());
|
||||
platform.SetConnection (conn_ap.release());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -276,16 +277,16 @@ main (int argc, char *argv[])
|
|||
}
|
||||
}
|
||||
|
||||
if (gdb_server.IsConnected())
|
||||
if (platform.IsConnected())
|
||||
{
|
||||
// After we connected, we need to get an initial ack from...
|
||||
if (gdb_server.HandshakeWithClient(&error))
|
||||
if (platform.HandshakeWithClient(&error))
|
||||
{
|
||||
bool interrupt = false;
|
||||
bool done = false;
|
||||
while (!interrupt && !done)
|
||||
{
|
||||
if (gdb_server.GetPacketAndSendResponse (UINT32_MAX, error, interrupt, done) != GDBRemoteCommunication::PacketResult::Success)
|
||||
if (platform.GetPacketAndSendResponse (UINT32_MAX, error, interrupt, done) != GDBRemoteCommunication::PacketResult::Success)
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue