]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Fix for bug 91162: cope with jumps to bogus addresses when there is a SEGV
authorNicholas Nethercote <n.nethercote@gmail.com>
Wed, 13 Oct 2004 09:58:53 +0000 (09:58 +0000)
committerNicholas Nethercote <n.nethercote@gmail.com>
Wed, 13 Oct 2004 09:58:53 +0000 (09:58 +0000)
signal handler present -- previously, Valgrind would abort unnecessarily on
this case.

Added a regression test for it.

MERGED FROM HEAD

git-svn-id: svn://svn.valgrind.org/valgrind/branches/VALGRIND_2_2_0_BRANCH@2745

coregrind/vg_include.h
coregrind/vg_scheduler.c
coregrind/vg_translate.c
memcheck/tests/.cvsignore
memcheck/tests/Makefile.am

index 3c882c6a76e4a0a527dd58243e467b37d1baa26f..ce84d1e6e539813631ec9cf150deb6fff0c290d3 100644 (file)
@@ -1160,7 +1160,7 @@ struct _UCodeBlock {
    Int     nextTemp;
 };
 
-extern void VG_(translate)  ( ThreadId tid, Addr orig_addr, Bool debugging );
+extern Bool VG_(translate)  ( ThreadId tid, Addr orig_addr, Bool debugging );
 
 extern void VG_(sanity_check_UInstr) ( UInt n, UInstr* u );
 
index ceede65ee39d3eff0ac9ecb55579a7d786a725ef..a42f6dcb29de417982a22e4b47341be3904f074b 100644 (file)
@@ -1021,17 +1021,29 @@ VgSchedReturnCode do_scheduler ( Int* exitcode, ThreadId* last_run_tid )
             thread. */
 
          if (trc == VG_TRC_INNER_FASTMISS) {
+            Addr ip = VG_(threads)[tid].m_eip;
+
             vg_assert(VG_(dispatch_ctr) > 0);
 
             /* Trivial event.  Miss in the fast-cache.  Do a full
                lookup for it. */
-            trans_addr = VG_(search_transtab) ( VG_(threads)[tid].m_eip );
+            trans_addr = VG_(search_transtab) ( ip );
             if (trans_addr == (Addr)0) {
                /* Not found; we need to request a translation. */
-               VG_(translate)( tid, VG_(threads)[tid].m_eip, /*debug*/False ); 
-               trans_addr = VG_(search_transtab) ( VG_(threads)[tid].m_eip ); 
-               if (trans_addr == (Addr)0)
-                  VG_(core_panic)("VG_TRC_INNER_FASTMISS: missing tt_fast entry");
+               if (VG_(translate)( tid, ip, /*debug*/False )) {
+                  trans_addr = VG_(search_transtab)( ip ); 
+                  if (trans_addr == (Addr)0)
+                     VG_(core_panic)("VG_TRC_INNER_FASTMISS: missing tt_fast entry");
+               } else {
+                  // If VG_(translate)() fails, it's because it had to throw
+                  // a signal because the client jumped to a bad address.
+                  // This means VG_(deliver_signal)() will have been called
+                  // by now, and the program counter will now be pointing to
+                  // the start of the signal handler (if there is no
+                  // handler, things would have been aborted by now), so do
+                  // nothing, and things will work out next time around the
+                  // scheduler loop.
+               }
             }
             continue; /* with this thread */
          }
index 3659820110b946f26ad2d4fe887c9ae71a817df6..e4d42a7070466eb8d40106078b408e1cced83c86 100644 (file)
@@ -2428,7 +2428,7 @@ static void vg_realreg_liveness_analysis ( UCodeBlock* cb )
 
    'tid' is the identity of the thread needing this block.
 */
-void VG_(translate) ( ThreadId tid, Addr orig_addr,
+Bool VG_(translate) ( ThreadId tid, Addr orig_addr,
                       Bool debugging_translation )
 {
    Addr        trans_addr, redir, orig_addr0 = orig_addr;
@@ -2484,7 +2484,7 @@ void VG_(translate) ( ThreadId tid, Addr orig_addr,
       } else
         VG_(synth_fault_mapping)(tid, orig_addr);
 
-      return;
+      return False;
    } else
       seg->flags |= SF_CODE;   /* contains cached code */
 
@@ -2583,6 +2583,8 @@ void VG_(translate) ( ThreadId tid, Addr orig_addr,
    VG_(arena_free)( VG_AR_JITTER, (void*)trans_addr );
 
    VGP_POPCC(VgpTranslate);
+
+   return True;
 }
 
 
index 915d772904e71d83faf9cbe31156f4fbf2b49549..e1acf9b8a1d12369e721618dc4fe463673aff4ac 100644 (file)
@@ -3,6 +3,7 @@ Makefile
 badaddrvalue
 badfree
 badjump
+badjump2
 badloop
 buflen_check
 clientperm
index a8fccb8c5520b057ce4330ad2bf62bde7b94f1ae..7c2727e16e19780c2e2d757b1d91ef1f1720559a 100644 (file)
@@ -15,6 +15,7 @@ EXTRA_DIST = $(noinst_SCRIPTS) \
        badfree-2trace.stderr.exp badfree-2trace.vgtest \
        badfree.stderr.exp badfree.vgtest \
        badjump.stderr.exp badjump.vgtest \
+       badjump2.stderr.exp badjump2.vgtest \
        badloop.stderr.exp badloop.vgtest \
        badrw.stderr.exp badrw.vgtest \
        brk.stderr.exp brk.vgtest \
@@ -78,7 +79,8 @@ EXTRA_DIST = $(noinst_SCRIPTS) \
        zeropage.stderr.exp zeropage.vgtest
 
 check_PROGRAMS = \
-       badaddrvalue badfree badjump badloop badrw brk brk2 buflen_check \
+       badaddrvalue badfree badjump badjump2 \
+       badloop badrw brk brk2 buflen_check \
        clientperm custom_alloc \
        doublefree error_counts errs1 exitprog execve execve2 \
        fpeflags fprw fwrite inits inline \
@@ -98,6 +100,7 @@ AM_CXXFLAGS = $(AM_CFLAGS)
 badaddrvalue_SOURCES   = badaddrvalue.c
 badfree_SOURCES        = badfree.c
 badjump_SOURCES        = badjump.c
+badjump2_SOURCES       = badjump2.c
 badloop_SOURCES        = badloop.c
 badrw_SOURCES          = badrw.c
 brk_SOURCES            = brk.c