forked from OSchip/llvm-project
[LLGS] Spawned process handling cleanup
Summary: This commit moves the m_spawned_pids member from the common LLGS/Platform class to the plaform specific part. This enables us to remove LLGS code, which was attempting to manage the m_spawned_pids contents, but at the same time making sure, there is only one debugged process. If we ever want to do multi-process debugging, we will probably want to replace this with a set of NativeProcessProtocolSP anyway. The only functional change is that support for qKillSpawnedProcess packet is removed from LLGS, but this was not used there anyway (we have the k packet for that). Reviewers: ovyalov, clayborg Subscribers: lldb-commits Differential Revision: http://reviews.llvm.org/D11557 llvm-svn: 243513
This commit is contained in:
parent
a6c31703ac
commit
6e4f19d440
|
@ -58,8 +58,6 @@ using namespace lldb_private::process_gdb_remote;
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
GDBRemoteCommunicationServerCommon::GDBRemoteCommunicationServerCommon(const char *comm_name, const char *listener_name) :
|
GDBRemoteCommunicationServerCommon::GDBRemoteCommunicationServerCommon(const char *comm_name, const char *listener_name) :
|
||||||
GDBRemoteCommunicationServer (comm_name, listener_name),
|
GDBRemoteCommunicationServer (comm_name, listener_name),
|
||||||
m_spawned_pids (),
|
|
||||||
m_spawned_pids_mutex (Mutex::eMutexTypeRecursive),
|
|
||||||
m_process_launch_info (),
|
m_process_launch_info (),
|
||||||
m_process_launch_error (),
|
m_process_launch_error (),
|
||||||
m_proc_infos (),
|
m_proc_infos (),
|
||||||
|
@ -79,8 +77,6 @@ GDBRemoteCommunicationServerCommon::GDBRemoteCommunicationServerCommon(const cha
|
||||||
&GDBRemoteCommunicationServerCommon::Handle_qGroupName);
|
&GDBRemoteCommunicationServerCommon::Handle_qGroupName);
|
||||||
RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qHostInfo,
|
RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qHostInfo,
|
||||||
&GDBRemoteCommunicationServerCommon::Handle_qHostInfo);
|
&GDBRemoteCommunicationServerCommon::Handle_qHostInfo);
|
||||||
RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qKillSpawnedProcess,
|
|
||||||
&GDBRemoteCommunicationServerCommon::Handle_qKillSpawnedProcess);
|
|
||||||
RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_QLaunchArch,
|
RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_QLaunchArch,
|
||||||
&GDBRemoteCommunicationServerCommon::Handle_QLaunchArch);
|
&GDBRemoteCommunicationServerCommon::Handle_QLaunchArch);
|
||||||
RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qLaunchSuccess,
|
RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qLaunchSuccess,
|
||||||
|
@ -484,94 +480,6 @@ GDBRemoteCommunicationServerCommon::Handle_qSpeedTest (StringExtractorGDBRemote
|
||||||
return SendErrorResponse (7);
|
return SendErrorResponse (7);
|
||||||
}
|
}
|
||||||
|
|
||||||
GDBRemoteCommunication::PacketResult
|
|
||||||
GDBRemoteCommunicationServerCommon::Handle_qKillSpawnedProcess (StringExtractorGDBRemote &packet)
|
|
||||||
{
|
|
||||||
packet.SetFilePos(::strlen ("qKillSpawnedProcess:"));
|
|
||||||
|
|
||||||
lldb::pid_t pid = packet.GetU64(LLDB_INVALID_PROCESS_ID);
|
|
||||||
|
|
||||||
// verify that we know anything about this pid.
|
|
||||||
// Scope for locker
|
|
||||||
{
|
|
||||||
Mutex::Locker locker (m_spawned_pids_mutex);
|
|
||||||
if (m_spawned_pids.find(pid) == m_spawned_pids.end())
|
|
||||||
{
|
|
||||||
// not a pid we know about
|
|
||||||
return SendErrorResponse (10);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// go ahead and attempt to kill the spawned process
|
|
||||||
if (KillSpawnedProcess (pid))
|
|
||||||
return SendOKResponse ();
|
|
||||||
else
|
|
||||||
return SendErrorResponse (11);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
GDBRemoteCommunicationServerCommon::KillSpawnedProcess (lldb::pid_t pid)
|
|
||||||
{
|
|
||||||
// make sure we know about this process
|
|
||||||
{
|
|
||||||
Mutex::Locker locker (m_spawned_pids_mutex);
|
|
||||||
if (m_spawned_pids.find(pid) == m_spawned_pids.end())
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// first try a SIGTERM (standard kill)
|
|
||||||
Host::Kill (pid, SIGTERM);
|
|
||||||
|
|
||||||
// check if that worked
|
|
||||||
for (size_t i=0; i<10; ++i)
|
|
||||||
{
|
|
||||||
{
|
|
||||||
Mutex::Locker locker (m_spawned_pids_mutex);
|
|
||||||
if (m_spawned_pids.find(pid) == m_spawned_pids.end())
|
|
||||||
{
|
|
||||||
// it is now killed
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
usleep (10000);
|
|
||||||
}
|
|
||||||
|
|
||||||
// check one more time after the final usleep
|
|
||||||
{
|
|
||||||
Mutex::Locker locker (m_spawned_pids_mutex);
|
|
||||||
if (m_spawned_pids.find(pid) == m_spawned_pids.end())
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// the launched process still lives. Now try killing it again,
|
|
||||||
// this time with an unblockable signal.
|
|
||||||
Host::Kill (pid, SIGKILL);
|
|
||||||
|
|
||||||
for (size_t i=0; i<10; ++i)
|
|
||||||
{
|
|
||||||
{
|
|
||||||
Mutex::Locker locker (m_spawned_pids_mutex);
|
|
||||||
if (m_spawned_pids.find(pid) == m_spawned_pids.end())
|
|
||||||
{
|
|
||||||
// it is now killed
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
usleep (10000);
|
|
||||||
}
|
|
||||||
|
|
||||||
// check one more time after the final usleep
|
|
||||||
// Scope for locker
|
|
||||||
{
|
|
||||||
Mutex::Locker locker (m_spawned_pids_mutex);
|
|
||||||
if (m_spawned_pids.find(pid) == m_spawned_pids.end())
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// no luck - the process still lives
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
GDBRemoteCommunication::PacketResult
|
GDBRemoteCommunication::PacketResult
|
||||||
GDBRemoteCommunicationServerCommon::Handle_vFile_Open (StringExtractorGDBRemote &packet)
|
GDBRemoteCommunicationServerCommon::Handle_vFile_Open (StringExtractorGDBRemote &packet)
|
||||||
{
|
{
|
||||||
|
|
|
@ -12,7 +12,6 @@
|
||||||
|
|
||||||
// C Includes
|
// C Includes
|
||||||
// C++ Includes
|
// C++ Includes
|
||||||
#include <set>
|
|
||||||
|
|
||||||
// Other libraries and framework includes
|
// Other libraries and framework includes
|
||||||
#include "lldb/lldb-private-forward.h"
|
#include "lldb/lldb-private-forward.h"
|
||||||
|
@ -40,8 +39,6 @@ public:
|
||||||
~GDBRemoteCommunicationServerCommon();
|
~GDBRemoteCommunicationServerCommon();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::set<lldb::pid_t> m_spawned_pids;
|
|
||||||
Mutex m_spawned_pids_mutex;
|
|
||||||
ProcessLaunchInfo m_process_launch_info;
|
ProcessLaunchInfo m_process_launch_info;
|
||||||
Error m_process_launch_error;
|
Error m_process_launch_error;
|
||||||
ProcessInstanceInfoList m_proc_infos;
|
ProcessInstanceInfoList m_proc_infos;
|
||||||
|
@ -73,9 +70,6 @@ protected:
|
||||||
PacketResult
|
PacketResult
|
||||||
Handle_qSpeedTest (StringExtractorGDBRemote &packet);
|
Handle_qSpeedTest (StringExtractorGDBRemote &packet);
|
||||||
|
|
||||||
PacketResult
|
|
||||||
Handle_qKillSpawnedProcess (StringExtractorGDBRemote &packet);
|
|
||||||
|
|
||||||
PacketResult
|
PacketResult
|
||||||
Handle_vFile_Open (StringExtractorGDBRemote &packet);
|
Handle_vFile_Open (StringExtractorGDBRemote &packet);
|
||||||
|
|
||||||
|
@ -160,9 +154,6 @@ protected:
|
||||||
PacketResult
|
PacketResult
|
||||||
Handle_QLaunchArch (StringExtractorGDBRemote &packet);
|
Handle_QLaunchArch (StringExtractorGDBRemote &packet);
|
||||||
|
|
||||||
bool
|
|
||||||
KillSpawnedProcess (lldb::pid_t pid);
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
CreateProcessInfoResponse (const ProcessInstanceInfo &proc_info,
|
CreateProcessInfoResponse (const ProcessInstanceInfo &proc_info,
|
||||||
StreamString &response);
|
StreamString &response);
|
||||||
|
|
|
@ -264,17 +264,6 @@ GDBRemoteCommunicationServerLLGS::LaunchProcess ()
|
||||||
|
|
||||||
printf ("Launched '%s' as process %" PRIu64 "...\n", m_process_launch_info.GetArguments ().GetArgumentAtIndex (0), m_process_launch_info.GetProcessID ());
|
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.
|
|
||||||
lldb::pid_t pid;
|
|
||||||
if ((pid = m_process_launch_info.GetProcessID ()) != LLDB_INVALID_PROCESS_ID)
|
|
||||||
{
|
|
||||||
// add to spawned pids
|
|
||||||
Mutex::Locker locker (m_spawned_pids_mutex);
|
|
||||||
// On an lldb-gdbserver, we would expect there to be only one.
|
|
||||||
assert (m_spawned_pids.empty () && "lldb-gdbserver adding tracked process but one already existed");
|
|
||||||
m_spawned_pids.insert (pid);
|
|
||||||
}
|
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -287,48 +276,37 @@ GDBRemoteCommunicationServerLLGS::AttachToProcess (lldb::pid_t pid)
|
||||||
if (log)
|
if (log)
|
||||||
log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64, __FUNCTION__, pid);
|
log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64, __FUNCTION__, pid);
|
||||||
|
|
||||||
// Scope for mutex locker.
|
// Before we try to attach, make sure we aren't already monitoring something else.
|
||||||
|
if (m_debugged_process_sp && m_debugged_process_sp->GetID() != LLDB_INVALID_PROCESS_ID)
|
||||||
|
return Error("cannot attach to a process %" PRIu64 " when another process with pid %" PRIu64 " is being debugged.", pid, m_debugged_process_sp->GetID());
|
||||||
|
|
||||||
|
// Try to attach.
|
||||||
|
error = NativeProcessProtocol::Attach(pid, *this, m_mainloop, m_debugged_process_sp);
|
||||||
|
if (!error.Success ())
|
||||||
{
|
{
|
||||||
// Before we try to attach, make sure we aren't already monitoring something else.
|
fprintf (stderr, "%s: failed to attach to process %" PRIu64 ": %s", __FUNCTION__, pid, error.AsCString ());
|
||||||
Mutex::Locker locker (m_spawned_pids_mutex);
|
|
||||||
if (!m_spawned_pids.empty ())
|
|
||||||
{
|
|
||||||
error.SetErrorStringWithFormat ("cannot attach to a process %" PRIu64 " when another process with pid %" PRIu64 " is being debugged.", pid, *m_spawned_pids.begin());
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try to attach.
|
|
||||||
error = NativeProcessProtocol::Attach(pid, *this, m_mainloop, m_debugged_process_sp);
|
|
||||||
if (!error.Success ())
|
|
||||||
{
|
|
||||||
fprintf (stderr, "%s: failed to attach to process %" PRIu64 ": %s", __FUNCTION__, pid, error.AsCString ());
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Setup stdout/stderr mapping from inferior.
|
|
||||||
auto terminal_fd = m_debugged_process_sp->GetTerminalFileDescriptor ();
|
|
||||||
if (terminal_fd >= 0)
|
|
||||||
{
|
|
||||||
if (log)
|
|
||||||
log->Printf ("ProcessGDBRemoteCommunicationServerLLGS::%s setting inferior STDIO fd to %d", __FUNCTION__, terminal_fd);
|
|
||||||
error = SetSTDIOFileDescriptor (terminal_fd);
|
|
||||||
if (error.Fail ())
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (log)
|
|
||||||
log->Printf ("ProcessGDBRemoteCommunicationServerLLGS::%s ignoring inferior STDIO since terminal fd reported as %d", __FUNCTION__, terminal_fd);
|
|
||||||
}
|
|
||||||
|
|
||||||
printf ("Attached to process %" PRIu64 "...\n", pid);
|
|
||||||
|
|
||||||
// Add to list of spawned processes.
|
|
||||||
assert (m_spawned_pids.empty () && "lldb-gdbserver adding tracked process but one already existed");
|
|
||||||
m_spawned_pids.insert (pid);
|
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Setup stdout/stderr mapping from inferior.
|
||||||
|
auto terminal_fd = m_debugged_process_sp->GetTerminalFileDescriptor ();
|
||||||
|
if (terminal_fd >= 0)
|
||||||
|
{
|
||||||
|
if (log)
|
||||||
|
log->Printf ("ProcessGDBRemoteCommunicationServerLLGS::%s setting inferior STDIO fd to %d", __FUNCTION__, terminal_fd);
|
||||||
|
error = SetSTDIOFileDescriptor (terminal_fd);
|
||||||
|
if (error.Fail ())
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (log)
|
||||||
|
log->Printf ("ProcessGDBRemoteCommunicationServerLLGS::%s ignoring inferior STDIO since terminal fd reported as %d", __FUNCTION__, terminal_fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf ("Attached to process %" PRIu64 "...\n", pid);
|
||||||
|
|
||||||
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -830,17 +808,6 @@ GDBRemoteCommunicationServerLLGS::HandleInferiorState_Exited (NativeProcessProto
|
||||||
log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed to send stop notification for PID %" PRIu64 ", state: eStateExited", __FUNCTION__, process->GetID ());
|
log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed to send stop notification for PID %" PRIu64 ", state: eStateExited", __FUNCTION__, process->GetID ());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove the process from the list of spawned pids.
|
|
||||||
{
|
|
||||||
Mutex::Locker locker (m_spawned_pids_mutex);
|
|
||||||
if (m_spawned_pids.erase (process->GetID ()) < 1)
|
|
||||||
{
|
|
||||||
if (log)
|
|
||||||
log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed to remove PID %" PRIu64 " from the spawned pids list", __FUNCTION__, process->GetID ());
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Close the pipe to the inferior terminal i/o if we launched it
|
// Close the pipe to the inferior terminal i/o if we launched it
|
||||||
// and set one up.
|
// and set one up.
|
||||||
MaybeCloseInferiorTerminalConnection ();
|
MaybeCloseInferiorTerminalConnection ();
|
||||||
|
@ -1119,26 +1086,6 @@ GDBRemoteCommunicationServerLLGS::Handle_qC (StringExtractorGDBRemote &packet)
|
||||||
return SendPacketNoLock (response.GetData(), response.GetSize());
|
return SendPacketNoLock (response.GetData(), response.GetSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
|
||||||
GDBRemoteCommunicationServerLLGS::DebuggedProcessReaped (lldb::pid_t pid)
|
|
||||||
{
|
|
||||||
// reap a process that we were debugging (but not debugserver)
|
|
||||||
Mutex::Locker locker (m_spawned_pids_mutex);
|
|
||||||
return m_spawned_pids.erase(pid) > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
GDBRemoteCommunicationServerLLGS::ReapDebuggedProcess (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
|
|
||||||
{
|
|
||||||
GDBRemoteCommunicationServerLLGS *server = (GDBRemoteCommunicationServerLLGS *)callback_baton;
|
|
||||||
server->DebuggedProcessReaped (pid);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
GDBRemoteCommunication::PacketResult
|
GDBRemoteCommunication::PacketResult
|
||||||
GDBRemoteCommunicationServerLLGS::Handle_k (StringExtractorGDBRemote &packet)
|
GDBRemoteCommunicationServerLLGS::Handle_k (StringExtractorGDBRemote &packet)
|
||||||
{
|
{
|
||||||
|
@ -2737,9 +2684,6 @@ GDBRemoteCommunicationServerLLGS::Handle_D (StringExtractorGDBRemote &packet)
|
||||||
|
|
||||||
StopSTDIOForwarding();
|
StopSTDIOForwarding();
|
||||||
|
|
||||||
// Scope for mutex locker.
|
|
||||||
Mutex::Locker locker (m_spawned_pids_mutex);
|
|
||||||
|
|
||||||
// Fail if we don't have a current process.
|
// Fail if we don't have a current process.
|
||||||
if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID))
|
if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID))
|
||||||
{
|
{
|
||||||
|
@ -2748,14 +2692,6 @@ GDBRemoteCommunicationServerLLGS::Handle_D (StringExtractorGDBRemote &packet)
|
||||||
return SendErrorResponse (0x15);
|
return SendErrorResponse (0x15);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_spawned_pids.find(m_debugged_process_sp->GetID ()) == m_spawned_pids.end())
|
|
||||||
{
|
|
||||||
if (log)
|
|
||||||
log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed to find PID %" PRIu64 " in spawned pids list",
|
|
||||||
__FUNCTION__, m_debugged_process_sp->GetID ());
|
|
||||||
return SendErrorResponse (0x1);
|
|
||||||
}
|
|
||||||
|
|
||||||
lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
|
lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
|
||||||
|
|
||||||
// Consume the ';' after D.
|
// Consume the ';' after D.
|
||||||
|
@ -2786,7 +2722,6 @@ GDBRemoteCommunicationServerLLGS::Handle_D (StringExtractorGDBRemote &packet)
|
||||||
return SendErrorResponse (0x01);
|
return SendErrorResponse (0x01);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_spawned_pids.erase (m_debugged_process_sp->GetID ());
|
|
||||||
return SendOKResponse ();
|
return SendOKResponse ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -269,16 +269,6 @@ protected:
|
||||||
FindModuleFile (const std::string& module_path, const ArchSpec& arch) override;
|
FindModuleFile (const std::string& module_path, const ArchSpec& arch) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool
|
|
||||||
DebuggedProcessReaped (lldb::pid_t pid);
|
|
||||||
|
|
||||||
static bool
|
|
||||||
ReapDebuggedProcess (void *callback_baton,
|
|
||||||
lldb::pid_t pid,
|
|
||||||
bool exited,
|
|
||||||
int signal,
|
|
||||||
int status);
|
|
||||||
|
|
||||||
void
|
void
|
||||||
HandleInferiorState_Exited (NativeProcessProtocol *process);
|
HandleInferiorState_Exited (NativeProcessProtocol *process);
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,7 @@ using namespace lldb_private::process_gdb_remote;
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
GDBRemoteCommunicationServerPlatform::GDBRemoteCommunicationServerPlatform() :
|
GDBRemoteCommunicationServerPlatform::GDBRemoteCommunicationServerPlatform() :
|
||||||
GDBRemoteCommunicationServerCommon ("gdb-remote.server", "gdb-remote.server.rx_packet"),
|
GDBRemoteCommunicationServerCommon ("gdb-remote.server", "gdb-remote.server.rx_packet"),
|
||||||
|
m_spawned_pids_mutex (Mutex::eMutexTypeRecursive),
|
||||||
m_platform_sp (Platform::GetHostPlatform ()),
|
m_platform_sp (Platform::GetHostPlatform ()),
|
||||||
m_port_map (),
|
m_port_map (),
|
||||||
m_port_offset(0)
|
m_port_offset(0)
|
||||||
|
@ -52,6 +53,8 @@ GDBRemoteCommunicationServerPlatform::GDBRemoteCommunicationServerPlatform() :
|
||||||
&GDBRemoteCommunicationServerPlatform::Handle_qGetWorkingDir);
|
&GDBRemoteCommunicationServerPlatform::Handle_qGetWorkingDir);
|
||||||
RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qLaunchGDBServer,
|
RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qLaunchGDBServer,
|
||||||
&GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer);
|
&GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer);
|
||||||
|
RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qKillSpawnedProcess,
|
||||||
|
&GDBRemoteCommunicationServerPlatform::Handle_qKillSpawnedProcess);
|
||||||
RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qProcessInfo,
|
RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qProcessInfo,
|
||||||
&GDBRemoteCommunicationServerPlatform::Handle_qProcessInfo);
|
&GDBRemoteCommunicationServerPlatform::Handle_qProcessInfo);
|
||||||
RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_QSetWorkingDir,
|
RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_QSetWorkingDir,
|
||||||
|
@ -183,6 +186,94 @@ GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer (StringExtractorGD
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GDBRemoteCommunication::PacketResult
|
||||||
|
GDBRemoteCommunicationServerPlatform::Handle_qKillSpawnedProcess (StringExtractorGDBRemote &packet)
|
||||||
|
{
|
||||||
|
packet.SetFilePos(::strlen ("qKillSpawnedProcess:"));
|
||||||
|
|
||||||
|
lldb::pid_t pid = packet.GetU64(LLDB_INVALID_PROCESS_ID);
|
||||||
|
|
||||||
|
// verify that we know anything about this pid.
|
||||||
|
// Scope for locker
|
||||||
|
{
|
||||||
|
Mutex::Locker locker (m_spawned_pids_mutex);
|
||||||
|
if (m_spawned_pids.find(pid) == m_spawned_pids.end())
|
||||||
|
{
|
||||||
|
// not a pid we know about
|
||||||
|
return SendErrorResponse (10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// go ahead and attempt to kill the spawned process
|
||||||
|
if (KillSpawnedProcess (pid))
|
||||||
|
return SendOKResponse ();
|
||||||
|
else
|
||||||
|
return SendErrorResponse (11);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
GDBRemoteCommunicationServerPlatform::KillSpawnedProcess (lldb::pid_t pid)
|
||||||
|
{
|
||||||
|
// make sure we know about this process
|
||||||
|
{
|
||||||
|
Mutex::Locker locker (m_spawned_pids_mutex);
|
||||||
|
if (m_spawned_pids.find(pid) == m_spawned_pids.end())
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// first try a SIGTERM (standard kill)
|
||||||
|
Host::Kill (pid, SIGTERM);
|
||||||
|
|
||||||
|
// check if that worked
|
||||||
|
for (size_t i=0; i<10; ++i)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
Mutex::Locker locker (m_spawned_pids_mutex);
|
||||||
|
if (m_spawned_pids.find(pid) == m_spawned_pids.end())
|
||||||
|
{
|
||||||
|
// it is now killed
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
usleep (10000);
|
||||||
|
}
|
||||||
|
|
||||||
|
// check one more time after the final usleep
|
||||||
|
{
|
||||||
|
Mutex::Locker locker (m_spawned_pids_mutex);
|
||||||
|
if (m_spawned_pids.find(pid) == m_spawned_pids.end())
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// the launched process still lives. Now try killing it again,
|
||||||
|
// this time with an unblockable signal.
|
||||||
|
Host::Kill (pid, SIGKILL);
|
||||||
|
|
||||||
|
for (size_t i=0; i<10; ++i)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
Mutex::Locker locker (m_spawned_pids_mutex);
|
||||||
|
if (m_spawned_pids.find(pid) == m_spawned_pids.end())
|
||||||
|
{
|
||||||
|
// it is now killed
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
usleep (10000);
|
||||||
|
}
|
||||||
|
|
||||||
|
// check one more time after the final usleep
|
||||||
|
// Scope for locker
|
||||||
|
{
|
||||||
|
Mutex::Locker locker (m_spawned_pids_mutex);
|
||||||
|
if (m_spawned_pids.find(pid) == m_spawned_pids.end())
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// no luck - the process still lives
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
GDBRemoteCommunication::PacketResult
|
GDBRemoteCommunication::PacketResult
|
||||||
GDBRemoteCommunicationServerPlatform::Handle_qProcessInfo (StringExtractorGDBRemote &packet)
|
GDBRemoteCommunicationServerPlatform::Handle_qProcessInfo (StringExtractorGDBRemote &packet)
|
||||||
{
|
{
|
||||||
|
|
|
@ -12,6 +12,8 @@
|
||||||
|
|
||||||
#include "GDBRemoteCommunicationServerCommon.h"
|
#include "GDBRemoteCommunicationServerCommon.h"
|
||||||
|
|
||||||
|
#include <set>
|
||||||
|
|
||||||
namespace lldb_private {
|
namespace lldb_private {
|
||||||
namespace process_gdb_remote {
|
namespace process_gdb_remote {
|
||||||
|
|
||||||
|
@ -59,6 +61,8 @@ public:
|
||||||
SetPortOffset (uint16_t port_offset);
|
SetPortOffset (uint16_t port_offset);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
Mutex m_spawned_pids_mutex;
|
||||||
|
std::set<lldb::pid_t> m_spawned_pids;
|
||||||
lldb::PlatformSP m_platform_sp;
|
lldb::PlatformSP m_platform_sp;
|
||||||
|
|
||||||
PortMap m_port_map;
|
PortMap m_port_map;
|
||||||
|
@ -67,6 +71,9 @@ protected:
|
||||||
PacketResult
|
PacketResult
|
||||||
Handle_qLaunchGDBServer (StringExtractorGDBRemote &packet);
|
Handle_qLaunchGDBServer (StringExtractorGDBRemote &packet);
|
||||||
|
|
||||||
|
PacketResult
|
||||||
|
Handle_qKillSpawnedProcess (StringExtractorGDBRemote &packet);
|
||||||
|
|
||||||
PacketResult
|
PacketResult
|
||||||
Handle_qProcessInfo (StringExtractorGDBRemote &packet);
|
Handle_qProcessInfo (StringExtractorGDBRemote &packet);
|
||||||
|
|
||||||
|
@ -83,6 +90,9 @@ protected:
|
||||||
Handle_jSignalsInfo(StringExtractorGDBRemote &packet);
|
Handle_jSignalsInfo(StringExtractorGDBRemote &packet);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool
|
||||||
|
KillSpawnedProcess (lldb::pid_t pid);
|
||||||
|
|
||||||
bool
|
bool
|
||||||
DebugserverProcessReaped (lldb::pid_t pid);
|
DebugserverProcessReaped (lldb::pid_t pid);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue