From 4eac75bf3e2dd0ec9356680262d5faeeaba803b2 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Fri, 7 Nov 2003 23:09:48 +0000 Subject: [PATCH] Fix some bugs in syscall/signal handling: If the proxyLWP for a thread got a signal just as we were sending the syscall request to it, then we would end up running the syscall twice. The fix is to not check the results pipe while sending the syscall request - wait until we're in a better state for handling signals (the deadlock the results-read was supposed to avoid cannot actually happen). Related to that, if we're delivering a signal to a thread, and that thread is currently waiting for a syscall to complete, make sure we collect the syscall results before entering the signal handler (otherwise we may end up bogusly trying to restart the syscall by moving EIP back, even though it now points to the signal handler rather than the syscall instruction) This change also adds an assertion to VG_(restart_syscall) to make sure we were actually restarting a syscall and not just randomly changing EIP (this found the problem above). Also, make set/getitimer run in the proxyLWP context, so that they modify/read the proxyLWP's timers rather than the schedluer LWP's timers. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@2013 --- coregrind/vg_include.h | 1 + coregrind/vg_mylibc.c | 5 ++--- coregrind/vg_proxylwp.c | 34 ++++++++++++++++++++++++++++------ coregrind/vg_signals.c | 22 +++++++++++----------- coregrind/vg_syscalls.c | 21 +++++++++++++++++++-- docs/proxylwp.sxw | Bin 22403 -> 22521 bytes include/valgrind.h | 8 ++++++-- include/vg_kerneliface.h | 4 +--- 8 files changed, 68 insertions(+), 27 deletions(-) diff --git a/coregrind/vg_include.h b/coregrind/vg_include.h index 9229880ea..9eea7b508 100644 --- a/coregrind/vg_include.h +++ b/coregrind/vg_include.h @@ -1540,6 +1540,7 @@ extern void VG_(proxy_setsigmask)(ThreadId tid); extern void VG_(proxy_sigack) ( ThreadId tid, const vki_ksigset_t *); extern void VG_(proxy_abort_syscall) ( ThreadId tid ); extern void VG_(proxy_waitsig) ( void ); +extern void VG_(proxy_wait_sys) (ThreadId tid); extern void VG_(proxy_shutdown) ( void ); /* shut down the syscall workers */ extern Int VG_(proxy_resfd) ( void ); /* FD something can select on to know diff --git a/coregrind/vg_mylibc.c b/coregrind/vg_mylibc.c index 34fe6cc18..07144b2bb 100644 --- a/coregrind/vg_mylibc.c +++ b/coregrind/vg_mylibc.c @@ -1053,11 +1053,10 @@ Bool VG_(string_match) ( Char* pat, Char* str ) static inline ExeContext *get_real_execontext(Addr ret) { ExeContext *ec; - Addr ebp; + Addr esp, ebp; Addr stacktop; - Addr esp = (Addr)&esp; - asm("movl %%ebp, %0" : "=r" (ebp)); + asm("movl %%ebp, %0; movl %%esp, %1" : "=r" (ebp), "=r" (esp)); stacktop = (Addr)&VG_(stack)[VG_STACK_SIZE_W]; if (esp >= (Addr)&VG_(sigstack)[0] && esp < (Addr)&VG_(sigstack)[VG_STACK_SIZE_W]) stacktop = (Addr)&VG_(sigstack)[VG_STACK_SIZE_W]; diff --git a/coregrind/vg_proxylwp.c b/coregrind/vg_proxylwp.c index 6716b0a2e..9fc470ad3 100644 --- a/coregrind/vg_proxylwp.c +++ b/coregrind/vg_proxylwp.c @@ -558,7 +558,7 @@ static Int proxylwp(void *v) XXX how to distunguish between restartable and non-restartable syscalls? Does it matter? */ - reply.syscallno = tst->m_eax; + reply.syscallno = tst->syscallno; tst->m_eax = -VKI_ERESTARTSYS; px->state = PXS_IntReply; @@ -1181,6 +1181,15 @@ void VG_(proxy_results)(void) sys_wait_results(False, 0, PX_BAD); } +void VG_(proxy_wait_sys)(ThreadId tid) +{ + ThreadState *tst = VG_(get_ThreadState)(tid); + + vg_assert(tst->status == VgTs_WaitSys); + + sys_wait_results(True, tid, PX_RunSyscall); +} + /* Tell proxy about it's thread's updated signal mask */ void VG_(proxy_setsigmask)(ThreadId tid) { @@ -1266,20 +1275,33 @@ Int VG_(sys_issue)(int tid) vg_assert(proxy != NULL); vg_assert(proxy->tid == tid); + vg_assert(tst->status == VgTs_WaitSys); + + /* Clear the results pipe before we try to write to a proxy to + prevent a deadlock (the proxyLWP may be trying to write a result + back to the scheduler LWP, and therefore not be reading its + input pipe, which would then block the write below). + + XXX I think this can't happen - the pipe has 4k of buffering, + and can therefore fit many messages, but we can only have one + outstanding - the write below will not block forever. Fetching + results here can cause all kinds of confusion, because we + definitely don't want the complexity of trying to deliver a + signal right now. + */ + if (0) + VG_(proxy_results)(); req.request = PX_RunSyscall; tst->syscallno = tst->m_eax; tst->m_eax = -VKI_ERESTARTSYS; - /* clear the results pipe before we try to write to a proxy to - prevent a deadlock */ - VG_(proxy_results)(); res = VG_(write)(proxy->topx, &req, sizeof(req)); if (res != sizeof(req)) { - VG_(printf)("sys_issue: write to tid %d failed %d (not %d)\n", - tid, res, sizeof(req)); + VG_(message)(Vg_DebugMsg, "sys_issue: write to tid %d failed %d (not %d)\n", + tid, res, sizeof(req)); } return 0; } diff --git a/coregrind/vg_signals.c b/coregrind/vg_signals.c index 2a68ef247..76900d895 100644 --- a/coregrind/vg_signals.c +++ b/coregrind/vg_signals.c @@ -1389,7 +1389,6 @@ void VG_(deliver_signal) ( ThreadId tid, const vki_ksiginfo_t *info, Bool async { Int sigNo = info->si_signo; vki_ksigset_t handlermask; - enum ThreadStatus status; SCSS_Per_Signal *handler = &vg_scss.scss_per_sig[sigNo]; ThreadState *tst = VG_(get_ThreadState)(tid); @@ -1419,6 +1418,15 @@ void VG_(deliver_signal) ( ThreadId tid, const vki_ksiginfo_t *info, Bool async if (tst->status == VgTs_WaitSys) { vg_assert(tst->syscallno != -1); + /* OK, the thread was waiting for a syscall to complete. This + means that the proxy has either not yet processed the + RunSyscall request, or was processing it when the signal + came. Either way, it is going to give us some syscall + results right now, so wait for them to appear. This makes + the thread runnable again, so we're in the right state to run + the handler, and resume the syscall when we're done. */ + VG_(proxy_wait_sys)(tid); + if (0) VG_(printf)("signal %d interrupting syscall %d\n", sigNo, tst->syscallno); @@ -1459,23 +1467,17 @@ void VG_(deliver_signal) ( ThreadId tid, const vki_ksiginfo_t *info, Bool async VG_(handle_SCSS_change)( False /* lazy update */ ); } - status = tst->status; - - switch(status) { + switch(tst->status) { case VgTs_Runnable: break; case VgTs_WaitSys: - /* don't change status yet, because we're about to get a - message telling us the syscall was interrupted */ - break; - case VgTs_WaitJoiner: case VgTs_WaitJoinee: case VgTs_WaitMX: case VgTs_WaitCV: case VgTs_Sleeping: - status = VgTs_Runnable; + tst->status = VgTs_Runnable; break; case VgTs_Empty: @@ -1483,8 +1485,6 @@ void VG_(deliver_signal) ( ThreadId tid, const vki_ksiginfo_t *info, Bool async break; } - tst->status = status; - /* handler gets the union of the signal's mask and the thread's mask */ handlermask = handler->scss_mask; diff --git a/coregrind/vg_syscalls.c b/coregrind/vg_syscalls.c index 566ed0dd7..ab489a593 100644 --- a/coregrind/vg_syscalls.c +++ b/coregrind/vg_syscalls.c @@ -4173,7 +4173,6 @@ static const struct sys_info sys_info[] = { SYSBA(getpmsg, True), SYSB_(putpmsg, True), - SYSBA(getitimer, False), SYSBA(syslog, True), SYSB_(personality, False), SYSB_(chroot, False), @@ -4291,7 +4290,6 @@ static const struct sys_info sys_info[] = { SYSBA(sched_getparam, False), /* ??? */ SYSB_(sched_yield, False), /* ??? */ SYSB_(select, True), - SYSBA(setitimer, False), SYSB_(setfsgid32, False), SYSB_(setgid32, False), SYSB_(setgid, False), @@ -4332,9 +4330,12 @@ static const struct sys_info sys_info[] = { SYSB_(rt_sigsuspend, True), SYSBA(rt_sigtimedwait, True), SYSBA(rt_sigqueueinfo, False), + SYSBA(sigpending, True), /* not blocking, but must run in LWP context */ SYSBA(rt_sigpending, True), /* not blocking, but must run in LWP context */ SYSB_(alarm, True), /* not blocking, but must run in LWP context */ + SYSBA(setitimer, True), /* not blocking, but must run in LWP context */ + SYSBA(getitimer, True), /* not blocking, but must run in LWP context */ #if !SIGNAL_SIMULATION SYSBA(sigaltstack, False), @@ -4524,6 +4525,22 @@ void VG_(restart_syscall)(ThreadId tid) tst->m_eax = tst->syscallno; tst->m_eip -= 2; /* sizeof(int $0x80) */ + + /* Make sure our caller is actually sane, and we're really backing + back over a syscall. + + int $0x80 == CD 80 + */ + { + UChar *p = (UChar *)tst->m_eip; + + if (p[0] != 0xcd || p[1] != 0x80) + VG_(message)(Vg_DebugMsg, + "?! restarting over syscall at %p %02x %02x\n", + tst->m_eip, p[0], p[1]); + + vg_assert(p[0] == 0xcd && p[1] == 0x80); + } } /*--------------------------------------------------------------------*/ diff --git a/docs/proxylwp.sxw b/docs/proxylwp.sxw index 89c9e32e95954a7e11eabd9099b88912c51329da..38ceeaf78850def466b6774933141f56ac9b7bb8 100644 GIT binary patch delta 8976 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 n=J(7Ri|2xcoEC2t~PO^?3BXXMdU(Npm@=d9b delta 8863 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