mirror of
https://github.com/Zenithsiz/ftmemsim-valgrind.git
synced 2026-02-03 10:05:29 +00:00
Fix for bug 91162: cope with jumps to bogus addresses when there is a SEGV
signal handler present -- previously, Valgrind would abort unnecessarily on this case. Added a regression test for it. MERGE TO STABLE git-svn-id: svn://svn.valgrind.org/valgrind/trunk@2743
This commit is contained in:
parent
fd06d82b71
commit
ce3c7200a7
@ -1128,7 +1128,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 );
|
||||
|
||||
|
||||
@ -857,20 +857,29 @@ VgSchedReturnCode do_scheduler ( Int* exitcode, ThreadId* last_run_tid )
|
||||
thread. */
|
||||
|
||||
if (trc == VG_TRC_INNER_FASTMISS) {
|
||||
Addr ip = ARCH_INSTR_PTR(VG_(threads)[tid].arch);
|
||||
|
||||
vg_assert(VG_(dispatch_ctr) > 0);
|
||||
|
||||
/* Trivial event. Miss in the fast-cache. Do a full
|
||||
lookup for it. */
|
||||
trans_addr = VG_(search_transtab)
|
||||
( ARCH_INSTR_PTR(VG_(threads)[tid].arch) );
|
||||
trans_addr = VG_(search_transtab)( ip );
|
||||
if (trans_addr == (Addr)0) {
|
||||
/* Not found; we need to request a translation. */
|
||||
VG_(translate)( tid, ARCH_INSTR_PTR(VG_(threads)[tid].arch),
|
||||
/*debug*/False );
|
||||
trans_addr = VG_(search_transtab)
|
||||
( ARCH_INSTR_PTR(VG_(threads)[tid].arch) );
|
||||
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 */
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -3,6 +3,7 @@ Makefile
|
||||
badaddrvalue
|
||||
badfree
|
||||
badjump
|
||||
badjump2
|
||||
badloop
|
||||
buflen_check
|
||||
clientperm
|
||||
|
||||
@ -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
|
||||
|
||||
45
memcheck/tests/badjump2.c
Normal file
45
memcheck/tests/badjump2.c
Normal file
@ -0,0 +1,45 @@
|
||||
#include <assert.h>
|
||||
#include <setjmp.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
// Regression test for bug 91162: if a client had a SEGV signal handler,
|
||||
// and jumped to a bogus address, Valgrind would abort. With the fix,
|
||||
// the following test runs to completion correctly.
|
||||
|
||||
static jmp_buf myjmpbuf;
|
||||
|
||||
static
|
||||
void SIGSEGV_handler(int signum)
|
||||
{
|
||||
__builtin_longjmp(myjmpbuf, 1);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
struct sigaction sigsegv_new, sigsegv_saved;
|
||||
int res;
|
||||
|
||||
/* Install own SIGSEGV handler */
|
||||
sigsegv_new.sa_handler = SIGSEGV_handler;
|
||||
sigsegv_new.sa_flags = 0;
|
||||
sigsegv_new.sa_restorer = NULL;
|
||||
res = sigemptyset( &sigsegv_new.sa_mask );
|
||||
assert(res == 0);
|
||||
|
||||
res = sigaction( SIGSEGV, &sigsegv_new, &sigsegv_saved );
|
||||
assert(res == 0);
|
||||
|
||||
if (__builtin_setjmp(myjmpbuf) == 0) {
|
||||
// Jump to zero; will cause seg fault
|
||||
void (*fn)(void) = 0;
|
||||
fn();
|
||||
fprintf(stderr, "Got here??\n");
|
||||
} else {
|
||||
fprintf(stderr, "Signal caught, as expected\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
6
memcheck/tests/badjump2.stderr.exp
Normal file
6
memcheck/tests/badjump2.stderr.exp
Normal file
@ -0,0 +1,6 @@
|
||||
Jump to the invalid address stated on the next line
|
||||
at 0x........: ???
|
||||
by 0x........: __libc_start_main (...libc...)
|
||||
by 0x........: ...
|
||||
Address 0x........ is not stack'd, malloc'd or (recently) free'd
|
||||
Signal caught, as expected
|
||||
2
memcheck/tests/badjump2.vgtest
Normal file
2
memcheck/tests/badjump2.vgtest
Normal file
@ -0,0 +1,2 @@
|
||||
prog: badjump2
|
||||
vgopts: -q
|
||||
Loading…
x
Reference in New Issue
Block a user