|
From: Eli D. <el...@aa...> - 2021-09-13 15:42:02
|
Hello!
I have inherited a valgrind-based instrumentation tool, and I have
discovered a very strange error. I have an instrumentation function that
adds a call to a logging function. If said logging function contains an
if statement that evaluates to false, valgrind segfaults. If it contains
no if, or the if evaluates to true, the tool works fine. See this MVP:
static void BK_(log_call)(UInt dest) {
if (0x400000 < dest) {
VG_(printf)("Call of %u\n", dest);
}
}
static
IRSB* bk_instrument ( VgCallbackClosure* closure,
IRSB* bb,
const VexGuestLayout* layout,
const VexGuestExtents* vge,
const VexArchInfo* archinfo_host,
IRType gWordTy, IRType hWordTy )
{
IRSB *ibb = deepCopyIRSBExceptStmts(bb);
IRDirty *dirty = unsafeIRDirty_0_N(0, "log_call",
VG_(fnptr_to_fnentry)(&BK_(log_call)),
mkIRExprVec_1(IRConstExprArg(1000))
);
addStmtToIRSB(ibb, IRStmt_Dirty(dirty));
for (int i = 0; i < bb->stmts_used; i++) {
addStmtToIRSB(ibb, bb->stmts[i]);
}
VG_(printf)("\n\nOriginal BB: \n");
ppIRSB(bb);
VG_(printf)("New BB: \n");
ppIRSB(ibb);
VG_(printf)("------------------------------\n");
return ibb;
}
As-is, this will segfault. If I remove the `if (0x400000 < dest)`, swap
the sign of the if, or add another print statement above the if, it will
work as intended. This doesn't happen on all programs, and I'm running
this on mipsel, if that's relevant. I believe I have removed everything
else from the pass -- I'm pretty sure the error lies here, although I
have no idea how that could be the case
The exact segfault I get is
```
==8333==
==8333== Process terminating with default action of signal 11 (SIGSEGV)
==8333== Access not within mapped region at address 0x0
==8333== at 0x48ED8B0: ioctl (in /lib/libuClibc-0.9.33.2.so)
==8333== by 0x4913D0C: tcgetattr (in /lib/libuClibc-0.9.33.2.so)
==8333== If you believe this happened as a result of a stack
==8333== overflow in your program's main thread (unlikely but
==8333== possible), you can try to
increase the size of the
==8333== main thread stack using the --main-stacksize= flag.
==8333== The main thread stack size used in this run was 8388608.
==8333==
[ 97.868000] beck-mips32-lin/8333: potentially unexpected fatal signal 11.
[ 97.868000]
[ 97.868000] Cpu 0
[ 97.868000] $ 0 : 00000000 3000a400 00000000 0000000b
[ 97.868000] $ 4 : 0000208d 0000000b 00000000 00000000
[ 97.868000] $ 8 : 41d1a010 00000000 420b5ac0 420b9ad8
[ 97.868000] $12 : 420b9adc 00060528 0000006f fffffffe
[ 97.868000] $16 : 428b8e50 428b8eec 428b8edc 428b8e88
[ 97.868000] $20 : 582aeac0 58a8c03c 00000000 00000000
[ 97.868000] $24 : 00064541 58015080
[ 97.868000] $28 : 582b5880 428b8dd8 58bdc328 58015198
[ 97.868000] Hi : 00000000
[ 97.868000] Lo : 00000000
[ 97.868000] epc : 58015088 0x58015088
[ 97.868000] Not tainted
[ 97.872000] ra : 58015198 0x58015198
[ 97.872000] Status: 0000a413 USER EXL IE
[ 97.872000] Cause : 10800020
[ 97.872000] PrId : 00019300 (MIPS 24Kc)
```
and the basic block it's crashing on is
New BB:
IRSB {
t0:I32 t1:I32 t2:I32 t3:I32 t4:I64 t5:I32 t6:I32 t7:I32
t8:I32 t9:I32 t10:I32 t11:I32 t12:I32 t13:I32 t14:I32 t15:I32
t16:I32
DIRTY 1:I1 ::: log_call{0x58000208}(0x3E8:I32)
------ IMark(0x4000B4C, 4, 0) ------
t6 = GET:I32(132)
t7 = GET:I32(40)
t5 = Sub32(t6,t7)
PUT(40) = t5
PUT(136) = 0x4000B50:I32
------ IMark(0x4000B50, 4, 0) ------
t9 = GET:I32(120)
t8 = Add32(t9,0xFFFF801C:I32)
t10 = LDle:I32(t8)
------ IMark(0x4000B54, 4, 0) ------
t11 = Add32(t10,0x4B44:I32)
------ IMark(0x4000B58, 4, 0) ------
t13 = Add32(t11,t5)
PUT(108) = t13
------ IMark(0x4000B5C, 4, 0) ------
PUT(132) = 0x4000B64:I32
------ IMark(0x4000B60, 4, 0) ------
PUT(136) = t13; exit-Call
}
If anyone has any advice on what's wrong with this code or suggestions
on how to debug it further, it would be very much appreciated!
|