Use getpgid() with waitpid() in case the process pgid is not equal to its pid, as is the case with a forked subprocess. Also a couple of fixes for unit test failures from Todd Fiala.

llvm-svn: 205405
This commit is contained in:
Andrew MacPherson 2014-04-02 06:57:45 +00:00
parent b461b1c785
commit 82aae0d835
6 changed files with 147 additions and 4 deletions

View File

@ -169,7 +169,7 @@ MonitorChildProcessThreadFunction (void *arg)
const bool monitor_signals = info->monitor_signals;
assert (info->pid <= UINT32_MAX);
const ::pid_t pid = monitor_signals ? -1 * info->pid : info->pid;
const ::pid_t pid = monitor_signals ? -1 * getpgid(info->pid) : info->pid;
delete info;

View File

@ -1742,7 +1742,7 @@ ProcessMonitor::StopThread(lldb::tid_t tid)
int status = -1;
if (log)
log->Printf ("ProcessMonitor::%s(bp) waitpid...", __FUNCTION__);
lldb::pid_t wait_pid = ::waitpid (-1*m_pid, &status, __WALL);
lldb::pid_t wait_pid = ::waitpid (-1*getpgid(m_pid), &status, __WALL);
if (log)
log->Printf ("ProcessMonitor::%s(bp) waitpid, pid = %" PRIu64 ", status = %d", __FUNCTION__, wait_pid, status);

View File

@ -379,6 +379,8 @@ ProcessPOSIX::DoDidExec()
void
ProcessPOSIX::SendMessage(const ProcessMessage &message)
{
Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
Mutex::Locker lock(m_message_mutex);
Mutex::Locker thread_lock(m_thread_list.GetMutex());
@ -420,8 +422,14 @@ ProcessPOSIX::SendMessage(const ProcessMessage &message)
break;
case ProcessMessage::eExitMessage:
assert(thread);
thread->SetState(eStateExited);
if (thread != nullptr)
thread->SetState(eStateExited);
else
{
if (log)
log->Warning ("ProcessPOSIX::%s eExitMessage for TID %" PRIu64 " failed to find a thread to mark as eStateExited, ignoring", __FUNCTION__, message.GetTID ());
}
// FIXME: I'm not sure we need to do this.
if (message.GetTID() == GetID())
{

View File

@ -0,0 +1,8 @@
LEVEL = ../../make
C_SOURCES := main.c
LD_EXTRAS := -lpthread
EXE := AttachResume
include $(LEVEL)/Makefile.rules

View File

@ -0,0 +1,95 @@
"""
Test process attach/resume.
"""
import os, time
import unittest2
import lldb
from lldbtest import *
import lldbutil
exe_name = "AttachResume" # Must match Makefile
class AttachResumeTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
@dwarf_test
def test_attach_continue_interrupt_detach(self):
"""Test attach/continue/interrupt/detach"""
self.buildDwarf()
self.process_attach_continue_interrupt_detach()
def process_attach_continue_interrupt_detach(self):
"""Test attach/continue/interrupt/detach"""
exe = os.path.join(os.getcwd(), exe_name)
popen = self.spawnSubprocess(exe)
self.addTearDownHook(self.cleanupSubprocesses)
self.runCmd("process attach -p " + str(popen.pid))
self._state = 0
def process_events():
event = lldb.SBEvent()
while self.dbg.GetListener().GetNextEvent(event):
self._state = lldb.SBProcess.GetStateFromEvent(event)
# using process.GetState() does not work: llvm.org/pr16172
def wait_for_state(s, timeout=5):
t = 0
period = 0.1
while self._state != s:
process_events()
time.sleep(period)
t += period
if t > timeout:
return False
return True
self.setAsync(True)
self.runCmd("c")
self.assertTrue(wait_for_state(lldb.eStateRunning),
'Process not running after continue')
self.runCmd("process interrupt")
self.assertTrue(wait_for_state(lldb.eStateStopped),
'Process not stopped after interrupt')
# be sure to continue/interrupt/continue (r204504)
self.runCmd("c")
self.assertTrue(wait_for_state(lldb.eStateRunning),
'Process not running after continue')
self.runCmd("process interrupt")
self.assertTrue(wait_for_state(lldb.eStateStopped),
'Process not stopped after interrupt')
# check that this breakpoint is auto-cleared on detach (r204752)
self.runCmd("br set -f main.c -l 12")
self.runCmd("c")
self.assertTrue(wait_for_state(lldb.eStateRunning),
'Process not running after continue')
self.assertTrue(wait_for_state(lldb.eStateStopped),
'Process not stopped after breakpoint')
self.expect('br list', 'Breakpoint not hit',
patterns = ['hit count = 1'])
self.runCmd("c")
self.assertTrue(wait_for_state(lldb.eStateRunning),
'Process not running after continue')
# make sure to detach while in running state (r204759)
self.runCmd("detach")
self.assertTrue(wait_for_state(lldb.eStateDetached),
'Process not detached after detach')
if __name__ == '__main__':
import atexit
lldb.SBDebugger.Initialize()
atexit.register(lambda: lldb.SBDebugger.Terminate())
unittest2.main()

View File

@ -0,0 +1,32 @@
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <pthread.h>
void *start(void *data)
{
int i;
size_t idx = (size_t)data;
for (i=0; i<30; i++)
{
if ( idx == 0 )
usleep(1);
sleep(1);
}
return 0;
}
int main(int argc, char const *argv[])
{
static const size_t nthreads = 16;
pthread_attr_t attr;
pthread_t threads[nthreads];
size_t i;
pthread_attr_init(&attr);
for (i=0; i<nthreads; i++)
pthread_create(&threads[i], &attr, &start, (void *)i);
for (i=0; i<nthreads; i++)
pthread_join(threads[i], 0);
}