Modified the host process monitor callback function Host::StartMonitoringChildProcess
to spawn a thread for each process that is being monitored. Previously
LLDB would spawn a single thread that would wait for any child process which
isn't ok to do as a shared library (LLDB.framework on Mac OSX, or lldb.so on
linux). The old single thread used to call wait4() with a pid of -1 which
could cause it to reap child processes that it shouldn't have.
Re-wrote the way Function blocks are handles. Previously I attempted to keep
all blocks in a single memory allocation (in a std::vector). This made the
code somewhat efficient, but hard to work with. I got rid of the old BlockList
class, and went to a straight parent with children relationship. This new
approach will allow for partial parsing of the blocks within a function.
git-svn-id: https://llvm.org/svn/llvm-project/llvdb/trunk@111706 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index 1c6b164..2a07ee9 100644
--- a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -110,7 +110,7 @@
m_byte_order (eByteOrderHost),
m_gdb_comm(),
m_debugserver_pid (LLDB_INVALID_PROCESS_ID),
- m_debugserver_monitor (0),
+ m_debugserver_thread (LLDB_INVALID_HOST_THREAD),
m_last_stop_packet (),
m_register_info (),
m_async_broadcaster ("lldb.process.gdb-remote.async-broadcaster"),
@@ -134,6 +134,13 @@
//----------------------------------------------------------------------
ProcessGDBRemote::~ProcessGDBRemote()
{
+ if (m_debugserver_thread != LLDB_INVALID_HOST_THREAD)
+ {
+ Host::ThreadCancel (m_debugserver_thread, NULL);
+ thread_result_t thread_result;
+ Host::ThreadJoin (m_debugserver_thread, &thread_result, NULL);
+ m_debugserver_thread = LLDB_INVALID_HOST_THREAD;
+ }
// m_mach_process.UnregisterNotificationCallbacks (this);
Clear();
}
@@ -535,11 +542,11 @@
m_gdb_comm.SendAck('+');
if (m_debugserver_pid != LLDB_INVALID_PROCESS_ID)
- m_debugserver_monitor = Host::StartMonitoringChildProcess (MonitorDebugserverProcess,
- (void*)(intptr_t)GetID(), // Pass the inferior pid in the thread argument (which is a void *)
- m_debugserver_pid,
- false);
-
+ m_debugserver_thread = Host::StartMonitoringChildProcess (MonitorDebugserverProcess,
+ this,
+ m_debugserver_pid,
+ false);
+
StringExtractorGDBRemote response;
if (m_gdb_comm.SendPacketAndWaitForResponse("QStartNoAckMode", response, 1, false))
{
@@ -1907,47 +1914,42 @@
// "debugserver_pid" argument passed in is the process ID for
// debugserver that we are tracking...
- lldb::pid_t gdb_remote_pid = (lldb::pid_t)(intptr_t)callback_baton;
- TargetSP target_sp(Debugger::FindTargetWithProcessID (gdb_remote_pid));
- if (target_sp)
+ ProcessGDBRemote *process = (ProcessGDBRemote *)callback_baton;
+
+ if (process)
{
- ProcessSP process_sp (target_sp->GetProcessSP());
- if (process_sp)
+ // Sleep for a half a second to make sure our inferior process has
+ // time to set its exit status before we set it incorrectly when
+ // both the debugserver and the inferior process shut down.
+ usleep (500000);
+ // If our process hasn't yet exited, debugserver might have died.
+ // If the process did exit, the we are reaping it.
+ if (process->GetState() != eStateExited)
{
- // Sleep for a half a second to make sure our inferior process has
- // time to set its exit status before we set it incorrectly when
- // both the debugserver and the inferior process shut down.
- usleep (500000);
- // If our process hasn't yet exited, debugserver might have died.
- // If the process did exit, the we are reaping it.
- if (process_sp->GetState() != eStateExited)
+ char error_str[1024];
+ if (signo)
{
- char error_str[1024];
- if (signo)
- {
- const char *signal_cstr = process_sp->GetUnixSignals().GetSignalAsCString (signo);
- if (signal_cstr)
- ::snprintf (error_str, sizeof (error_str), DEBUGSERVER_BASENAME " died with signal %s", signal_cstr);
- else
- ::snprintf (error_str, sizeof (error_str), DEBUGSERVER_BASENAME " died with signal %i", signo);
- }
+ const char *signal_cstr = process->GetUnixSignals().GetSignalAsCString (signo);
+ if (signal_cstr)
+ ::snprintf (error_str, sizeof (error_str), DEBUGSERVER_BASENAME " died with signal %s", signal_cstr);
else
- {
- ::snprintf (error_str, sizeof (error_str), DEBUGSERVER_BASENAME " died with an exit status of 0x%8.8x", exit_status);
- }
-
- process_sp->SetExitStatus (-1, error_str);
+ ::snprintf (error_str, sizeof (error_str), DEBUGSERVER_BASENAME " died with signal %i", signo);
}
else
{
- ProcessGDBRemote *gdb_process = (ProcessGDBRemote *)process_sp.get();
- // Debugserver has exited we need to let our ProcessGDBRemote
- // know that it no longer has a debugserver instance
- gdb_process->m_debugserver_pid = LLDB_INVALID_PROCESS_ID;
- // We are returning true to this function below, so we can
- // forget about the monitor handle.
- gdb_process->m_debugserver_monitor = 0;
+ ::snprintf (error_str, sizeof (error_str), DEBUGSERVER_BASENAME " died with an exit status of 0x%8.8x", exit_status);
}
+
+ process->SetExitStatus (-1, error_str);
+ }
+ else
+ {
+ // Debugserver has exited we need to let our ProcessGDBRemote
+ // know that it no longer has a debugserver instance
+ process->m_debugserver_pid = LLDB_INVALID_PROCESS_ID;
+ // We are returning true to this function below, so we can
+ // forget about the monitor handle.
+ process->m_debugserver_thread = LLDB_INVALID_HOST_THREAD;
}
}
return true;