]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Fix stupid bug in which vg_push_signal_frame/vg_pop_signal_frame assumed
authorJulian Seward <jseward@acm.org>
Wed, 18 Sep 2002 14:50:57 +0000 (14:50 +0000)
committerJulian Seward <jseward@acm.org>
Wed, 18 Sep 2002 14:50:57 +0000 (14:50 +0000)
that the handler wouldn't change the signal-number parameter it was passed.

Fixes this:
   vg_signals.c:1065 (vgPlain_signal_returns):
   Assertion `sigNo >= 1 && sigNo <= 64' failed.
and possibly arbitrary other mutancy in the signal handling too.

MERGE TO ERASER

git-svn-id: svn://svn.valgrind.org/valgrind/branches/VALGRIND_1_0_BRANCH@1074

vg_signals.c

index 27a4871e4f4b67b11edbc4f13110a3c4a3884454..39d365b621a90e33a9ed58b81ec4ade28de75131 100644 (file)
@@ -874,13 +874,30 @@ void VG_(restore_all_host_signals) ( /* IN */ vki_ksigset_t* saved_mask )
 
 typedef
    struct {
-      /* These are parameters to the signal handler. */
-      UInt retaddr;   /* Sig handler's (bogus) return address */
-      Int  sigNo;     /* The arg to the sig handler.  */
-      Addr psigInfo;  /* ptr to siginfo_t; NULL for now. */
-      Addr puContext; /* ptr to ucontext; NULL for now. */
+      /* These 4 are parameters to the signal handler.  The order of
+         them is important, since this whole struct is pushed onto the
+         client's stack at delivery time.  The first 4 words -- which
+         will be at the top of the stack -- constitute 4 arg words to
+         the handler. */
+
+      /* Sig handler's (bogus) return address */
+      Addr retaddr;
+      /* The arg to the sig handler.  We need to inspect this after
+         the handler returns, but it's unreasonable to assume that the
+         handler won't change it.  So we keep a second copy of it in
+         sigNo_private. */
+      Int  sigNo;
+      /* ptr to siginfo_t; NULL for now. */
+      Addr psigInfo;
+      /* ptr to ucontext; NULL for now. */
+      Addr puContext;
+
+      /* The rest are private fields which the handler is unaware of. */
+
       /* Sanity check word. */
       UInt magicPI;
+      /* Safely-saved version of sigNo, as described above. */
+      Int  sigNo_private;
       /* Saved processor state. */
       UInt fpustate[VG_SIZE_OF_FPUSTATE_W];
       UInt eax;
@@ -946,6 +963,7 @@ void vg_push_signal_frame ( ThreadId tid, int sigNo )
 
    frame->retaddr    = (UInt)(&VG_(signalreturn_bogusRA));
    frame->sigNo      = sigNo;
+   frame->sigNo_private = sigNo;
    frame->psigInfo   = (Addr)NULL;
    frame->puContext  = (Addr)NULL;
    frame->magicPI    = 0x31415927;
@@ -1035,7 +1053,10 @@ Int vg_pop_signal_frame ( ThreadId tid )
    tst->m_edi     = frame->edi;
    tst->m_eflags  = frame->eflags;
    tst->m_eip     = frame->eip;
-   sigNo          = frame->sigNo;
+
+   /* don't use the copy exposed to the handler; it might have changed
+      it. */
+   sigNo          = frame->sigNo_private; 
 
    /* And restore the thread's status to what it was before the signal
       was delivered. */