[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    valgrind [POSSIBLY UNSAFE]
From:       Jeremy Fitzhardinge <jeremy () goop ! org>
Date:       2004-01-16 2:15:23
Message-ID: 20040116021523.CD7099081 () office ! kde ! org
[Download RAW message or body]

CVS commit by fitzhardinge: 

Fix bug 72650.  Only restart syscalls on signal if the client asked for it.


  A            none/tests/syscall-restart1.c   1.1 [POSSIBLY UNSAFE: printf] [no copyright]
  A            none/tests/syscall-restart1.stderr.exp   1.1
  A            none/tests/syscall-restart1.stdout.exp   1.1
  A            none/tests/syscall-restart1.vgtest   1.1
  A            none/tests/syscall-restart2.c   1.1 [POSSIBLY UNSAFE: printf] [no copyright]
  A            none/tests/syscall-restart2.stderr.exp   1.1
  A            none/tests/syscall-restart2.stdout.exp   1.1
  A            none/tests/syscall-restart2.vgtest   1.1
  M +2 -2      coregrind/vg_include.h   1.168
  M +13 -13    coregrind/vg_proxylwp.c   1.12
  M +1 -1      coregrind/vg_scheduler.c   1.136
  M +5 -15     coregrind/vg_signals.c   1.57
  M +37 -18    coregrind/vg_syscalls.c   1.77
  M +5 -0      none/tests/Makefile.am   1.20


--- valgrind/none/tests/Makefile.am  #1.19:1.20
@@ -39,4 +39,6 @@
         shorts.stderr.exp shorts.vgtest \
         smc1.stderr.exp smc1.stdout.exp smc1.vgtest \
+        syscall-restart1.vgtest syscall-restart1.stdout.exp syscall-restart1.stderr.exp \
+        syscall-restart2.vgtest syscall-restart2.stdout.exp syscall-restart2.stderr.exp \
         yield.stdout.exp yield.vgtest
 
@@ -47,4 +49,5 @@
         rcrl readline1 resolv seg_override sha1_test shortpush shorts smc1 \
         pth_blockedsig \
+        syscall-restart1 syscall-restart2 \
         coolo_sigaction gxx304 yield
 
@@ -78,4 +81,6 @@
 shortpush_SOURCES       = shortpush.c
 shorts_SOURCES          = shorts.c
+syscall_restart1_SOURCES = syscall-restart1.c
+syscall_restart2_SOURCES = syscall-restart2.c
 yield_SOURCES           = yield.c
 yield_LDADD             = -lpthread

--- valgrind/coregrind/vg_proxylwp.c  #1.11:1.12
@@ -181,5 +181,5 @@ struct ProxyLWP {
 };
 
-static void sys_wait_results(Bool block, ThreadId tid, enum RequestType reqtype);
+static void sys_wait_results(Bool block, ThreadId tid, enum RequestType reqtype, Bool restart);
 
 struct PX_Request {
@@ -842,7 +842,7 @@ void VG_(proxy_sendsig)(ThreadId tid, In
          syscall to dinish. */
       if (tst->status == VgTs_WaitSys && tst->syscallno == __NR_rt_sigtimedwait)
-         sys_wait_results(True, tid, PX_RunSyscall);
+         sys_wait_results(True, tid, PX_RunSyscall, True);
       else
-         sys_wait_results(True, tid, PX_Signal);
+         sys_wait_results(True, tid, PX_Signal, True);
    }
 }
@@ -867,5 +867,5 @@ void VG_(proxy_abort_syscall)(ThreadId t
       VG_(ktkill)(lwp, VKI_SIGVGINT);
 
-   sys_wait_results(True, tid, PX_RunSyscall);
+   sys_wait_results(True, tid, PX_RunSyscall, False);
 
    vg_assert(tst->status == VgTs_Runnable);
@@ -1064,5 +1064,5 @@ void VG_(proxy_delete)(ThreadId tid, Boo
       may be blocked writing to it, causing a deadlock with us as we
       wait for it to exit. */
-   sys_wait_results(True, tid, PX_Exiting);
+   sys_wait_results(True, tid, PX_Exiting, True);
    res = proxy_wait(proxy, True, &status);
 
@@ -1092,5 +1092,5 @@ void VG_(proxy_delete)(ThreadId tid, Boo
    wait for a reply for that particular tid.
  */
-static void sys_wait_results(Bool block, ThreadId tid, enum RequestType reqtype)
+static void sys_wait_results(Bool block, ThreadId tid, enum RequestType reqtype, Bool restart)
 {
    Bool found_reply = (reqtype == PX_BAD);
@@ -1154,5 +1154,5 @@ static void sys_wait_results(Bool block,
             vg_assert(tst->status == VgTs_WaitSys);
 
-            VG_(post_syscall)(res.tid);
+            VG_(post_syscall)(res.tid, restart);
             break;
 
@@ -1188,8 +1188,8 @@ static void sys_wait_results(Bool block,
 void VG_(proxy_results)(void)
 {
-   sys_wait_results(False, 0, PX_BAD);
+   sys_wait_results(False, 0, PX_BAD, True);
 }
 
-void VG_(proxy_wait_sys)(ThreadId tid)
+void VG_(proxy_wait_sys)(ThreadId tid, Bool restart)
 {
    ThreadState *tst = VG_(get_ThreadState)(tid);
@@ -1197,5 +1197,5 @@ void VG_(proxy_wait_sys)(ThreadId tid)
    vg_assert(tst->status == VgTs_WaitSys);
 
-   sys_wait_results(True, tid, PX_RunSyscall);
+   sys_wait_results(True, tid, PX_RunSyscall, restart);
 }
 
@@ -1227,5 +1227,5 @@ void VG_(proxy_setsigmask)(ThreadId tid)
       updates their signal masks, A's update must be done before B's
       is).  */
-   sys_wait_results(True, tid, PX_SetSigmask);
+   sys_wait_results(True, tid, PX_SetSigmask, True);
 }
 
@@ -1272,5 +1272,5 @@ void VG_(proxy_waitsig)(void)
       VG_(route_signals)();
    else
-      sys_wait_results(True, VG_INVALID_THREADID /* any */, PX_Signal);
+      sys_wait_results(True, VG_INVALID_THREADID /* any */, PX_Signal, True);
 }
 
@@ -1365,5 +1365,5 @@ void VG_(proxy_sanity)(void)
             sane = False;
          }
-         sys_wait_results(True, tid, PX_Ping);
+         sys_wait_results(True, tid, PX_Ping, True);
          /* Can't make an assertion here, fortunately; this will
             either come back or it won't. */

--- valgrind/coregrind/vg_signals.c  #1.56:1.57
@@ -1448,20 +1448,10 @@ void VG_(deliver_signal) ( ThreadId tid,
          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);
-
+         the handler.  We ask post_syscall to restart based on the
+         client's sigaction flags. */
       if (0)
-         VG_(printf)("signal %d interrupting syscall %d\n",
-                     sigNo, tst->syscallno);
-
-      if (tst->m_eax == -VKI_ERESTARTSYS) {
-          if (handler->scss_flags & VKI_SA_RESTART) {
-             VG_(restart_syscall)(tid);
-          } else
-             tst->m_eax = -VKI_EINTR;
-      } else {
-         /* return value is already in eax - either EINTR or the
-            normal return value */
-      }
+         VG_(printf)("signal %d interrupted syscall %d; restart=%d\n",
+                     sigNo, tst->syscallno, !!(handler->scss_flags & VKI_SA_RESTART));
+      VG_(proxy_wait_sys)(tid, !!(handler->scss_flags & VKI_SA_RESTART));
    }
 

--- valgrind/coregrind/vg_include.h  #1.167:1.168
@@ -1608,5 +1608,5 @@ extern void VG_(proxy_sigack)   ( Thread
 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_wait_sys) (ThreadId tid, Bool restart);
 
 extern void VG_(proxy_shutdown) ( void );       /* shut down the syscall workers */
@@ -1631,5 +1631,5 @@ extern Char *VG_(resolve_filename)(Int f
 
 extern Bool VG_(pre_syscall) ( ThreadId tid );
-extern void VG_(post_syscall)( ThreadId tid );
+extern void VG_(post_syscall)( ThreadId tid, Bool restart );
 extern void VG_(restart_syscall) ( ThreadId tid );
 

--- valgrind/coregrind/vg_scheduler.c  #1.135:1.136
@@ -700,5 +700,5 @@ void sched_do_syscall ( ThreadId tid )
    /* If pre_syscall returns true, then we're done immediately */
    if (VG_(pre_syscall)(tid)) {
-      VG_(post_syscall(tid));
+      VG_(post_syscall(tid, True));
       vg_assert(VG_(threads)[tid].status == VgTs_Runnable);
    } else {

--- valgrind/coregrind/vg_syscalls.c  #1.76:1.77
@@ -5243,5 +5243,5 @@ Bool VG_(pre_syscall) ( ThreadId tid )
 
 
-void VG_(post_syscall) ( ThreadId tid )
+void VG_(post_syscall) ( ThreadId tid, Bool restart )
 {
    ThreadState* tst;
@@ -5249,4 +5249,5 @@ void VG_(post_syscall) ( ThreadId tid )
    const struct sys_info *sys;
    Bool special = False;
+   Bool restarted = False;
    void *pre_res;
 
@@ -5273,8 +5274,34 @@ void VG_(post_syscall) ( ThreadId tid )
    }
 
+   if (tst->m_eax == -VKI_ERESTARTSYS) {
+      /* Applications never expect to see this, so we should either
+         restart the syscall or fail it with EINTR, depending on what
+         our caller wants.  Generally they'll want to restart, but if
+         client set the signal state to not restart, then we fail with
+         EINTR.  Either way, ERESTARTSYS means the syscall made no
+         progress, and so can be failed or restarted without
+         consequence. */
+      if (0)
+         VG_(printf)("syscall %d returned ERESTARTSYS; restart=%d\n",
+                     syscallno, restart);
+
+      if (restart) {
+         restarted = True;
+         VG_(restart_syscall)(tid);
+      } else
+         tst->m_eax = -VKI_EINTR;
+   } 
+
+   if (!restarted) {
    if (!VG_(is_kerror)(tst->m_eax) && sys->after != NULL)
       (sys->after)(tst->tid, tst);
 
-   /* Do any post-syscall actions */
+      /* Do any post-syscall actions
+
+         NOTE: this is only called if the syscall completed.  If the
+         syscall was restarted, then it will call the Tool's
+         pre_syscall again, without calling post_syscall (ie, more
+         pre's than post's)
+       */
    if (VG_(needs).syscall_wrapper) {
       VGP_PUSHCC(VgpSkinSysWrap);
@@ -5282,16 +5309,8 @@ void VG_(post_syscall) ( ThreadId tid )
       VGP_POPCC(VgpSkinSysWrap);
    }
-
-   if (tst->m_eax == -VKI_ERESTARTSYS) {
-      /* Applications never expect to see this, so we should actually
-         restart the syscall (it means the signal happened before the
-         syscall made any progress, so we can safely restart it and
-         pretend the signal happened before the syscall even
-         started)  */
-      VG_(restart_syscall)(tid);
    }
 
    tst->status = VgTs_Runnable; /* runnable again */
-   tst->syscallno = -1;
+   tst->syscallno = -1;         /* no current syscall */
 
    VGP_POPCC(VgpCoreSysWrap);


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic