DynamoRIO / DynamoRIO/dynamorio

ASSERT in client.exception on SIGSEGV at pc==0

Open
#7,297 1 comment 0 reactions 0 assignees View on GitHub
Bug-Assert Bug-ToolCrash OpSys-Linux
Dominant language
C
Stars
3.2k
Forks
629
Avg merge
2d 18h
Merged PRs (30d)
30

Description

The client.exception test exercises a C++ exception in dr_init.

On recent Linux it fails with an assert:
```
Assert failure: core/unix/signal.c:6065 pc != 0
```

Debugging:
```
about to throw

Program received signal SIGSEGV, Segmentation fault.
0x0000000000000000 in ?? ()
(gdb) bt
#0 0x0000000000000000 in ?? ()
#1 0x00007ffff79bad16 in _Unwind_Find_FDE ()
#2 0x00007ffff79b7453 in ?? ()
#3 0x00007ffff79b86f0 in ?? ()
#4 0x00007ffff79b8c79 in _Unwind_RaiseException ()
#5 0x00007ffff72ae4cb in __cxa_throw ()
#6 0x00007fffb3809347 in dr_init (id=0) at /home/derek/dr/git/src/suite/tests/client-interface/exception.dll.cpp:72
#7 0x00007ffff7bff591 in instrument_init () at /home/derek/dr/git/src/core/lib/instrument.c:797
#8 0x00007ffff7a6135d in dynamorio_app_init_part_two_finalize () at /home/derek/dr/git/src/core/dynamo.c:716
#9 0x00007ffff7d24f3f in privload_early_inject (sp=0x7fffffffe370, old_libdr_base=0x0, old_libdr_size=1) at /home/derek/dr/git/src/core/unix/loader.c:2379
#10 0x00007ffff7cc9efc in reloaded_xfer () at /home/derek/dr/git/src/core/arch/x86/x86.asm:1179
(gdb) p $_siginfo
$1 = {si_signo = 11, si_errno = 0, si_code = 1, _sifields = {_pad = {0 }, _kill = {si_pid = 0, si_uid = 0}, _timer = {si_tid = 0, si_overrun = 0, si_sigval = {
sival_int = 0, sival_ptr = 0x0}}, _rt = {si_pid = 0, si_uid = 0, si_sigval = {sival_int = 0, sival_ptr = 0x0}}, _sigchld = {si_pid = 0, si_uid = 0, si_status = 0,
si_utime = 0, si_stime = 0}, _sigfault = {si_addr = 0x0, _addr_lsb = 0, _addr_bnd = {_lower = 0x0, _upper = 0x0}}, _sigpoll = {si_band = 0, si_fd = 0}, _sigsys = {
_call_addr = 0x0, _syscall = 0, _arch = 0}}}

Dump of assembler code for function _Unwind_Find_FDE:
0x00007ffff79bace0 <+0>: endbr64
0x00007ffff79bace4 <+4>: push %r15
0x00007ffff79bace6 <+6>: push %r14
0x00007ffff79bace8 <+8>: push %r13
0x00007ffff79bacea <+10>: push %r12
0x00007ffff79bacec <+12>: mov %rsi,%r12
0x00007ffff79bacef <+15>: push %rbp
0x00007ffff79bacf0 <+16>: mov %rdi,%rbp
0x00007ffff79bacf3 <+19>: push %rbx
0x00007ffff79bacf4 <+20>: sub $0xb8,%rsp
0x00007ffff79bacfb <+27>: mov 0x6587(%rip),%eax # 0x7ffff79c1288
0x00007ffff79bad01 <+33>: test %eax,%eax
0x00007ffff79bad03 <+35>: jne 0x7ffff79baea0 <_Unwind_Find_FDE+448>
0x00007ffff79bad09 <+41>: lea 0x50(%rsp),%rsi
0x00007ffff79bad0e <+46>: mov %rbp,%rdi
0x00007ffff79bad11 <+49>: call 0x7ffff79a5560
0x00007ffff79bad16 <+54>: test %eax,%eax

(gdb) x/10i 0x7ffff79a5560
0x7ffff79a5560: endbr64
0x7ffff79a5564: bnd jmp *0x1bbb5(%rip) # 0x7ffff79c1120
(gdb) x/1gx 0x7ffff79c1120
0x7ffff79c1120: 0x00007ffff6f75b10
(gdb) x/10i 0x00007ffff6f75b10
0x7ffff6f75b10 <_dl_find_object>: endbr64
0x7ffff6f75b14 <_dl_find_object+4>: mov 0xa43ad(%rip),%rax # 0x7ffff7019ec8
0x7ffff6f75b1b <_dl_find_object+11>: jmp *0x378(%rax)
(gdb) x/1gx 0x7ffff7019ec8
0x7ffff7019ec8: 0x00007ffff79fcae0
(gdb) x/1gx 0x00007ffff79fcae0+0x378
0x7ffff79fce58: 0x0000000000000000
```

si_code == 1 == SEGV_MAPERR

Stepping through: indeed it jumps to 0.

Xref C++ exception code in the past needing redirect_dl_iterate_phdr which
wasn't too hard to provide.

Looks like it now uses this internal dl_find_object which has data
structures with fields for exception handling.
Looks complicated: much more complex than dl_iterate_phdr.

Hmm: maybe this is another reason to switch the private loader on
Linux/Android to have the system ld.so load the client + private libraries:
#5437.

I don't think there's any easy short term fix: have to drop support for C++ exceptions in clients?

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.