SIGSEGV due to wrong stolen reg value after synchall
While working on PR #4491 which adds a synchall to drcachesim while enabling tracing, I encountered a crash due to the stolen reg having a value that doesn't seem like an address.
The segfaulting threads were redirected to the reset exit stub by DR at [1]. The SIGSEGV
occurs in the exit stub shown below.
Thread xxx received signal SIGSEGV, Segmentation fault.
0x0000000046fc2458 in ?? ()
(gdb) x/50i 0x46fc2458
=> 0x46fc2458: stp x0, x1, [x28]
0x46fc245c: mov x0, #0x4c20 // #19488
0x46fc2460: movk x0, #0xf7f0, lsl #16
0x46fc2464: movk x0, #0xffff, lsl #32
0x46fc2468: ldr x1, [x28, #64]
0x46fc246c: br x1
...
The exit stub expects the stolen reg to be set up already, but it doesn't seem to be -- see x28
below.
(gdb) i r
x0 0xfffffffffffffffc -4
x1 0xfffff45bcc80 281474781400192
...
x28 0x30000 196608
...
pc 0x46fc2458 0x46fc2458
The issue was fixed by adding a stolen reg store. Also there's a bug in the reset tests linux.thread-reset
and linux.clone-reset
, due to which they don't fail on AArch64 when they should.
Filing and fixing these separately from the PR #4491.
[1]: translate_from_synchall_to_dispatch
https://github.com/DynamoRIO/dynamorio/blob/9bedb9c72d5808785e28d20df3ed1c932b555ac9/core/synch.c#L1816