DynamoRIO / DynamoRIO/dynamorio
Auto-restart syscall on SIG_IGN erroneously removed from drmemtrace
- Dominant language
- C
- Stars
- 3.2k
- Forks
- 629
- Avg merge
- 2d 15h
- Merged PRs (30d)
- 31
Description
Running drmemtrace offline on the `linux.eintr` test with PR #6096 adding syscall markers we see a strange back-to-back marker with no syscall instruction in between:
```
5304 3709: 1684319 ifetch 2 byte(s) @ 0x00007f08dc14412a 0f 05 syscall
5305 3709: 1684319
5306 3709: 1684319
5307 3709: 1684319
5308 3709: 1684319
5309 3709: 1684319
5310 3709: 1684319
5311 3709: 1684319
5312 3709: 1684319
5313 3709: 1684319
5314 3709: 1684319
5315 3709: 1684319
5316 3710: 1684319 ifetch 1 byte(s) @ 0x00007f08d87fa7fa 55 push %rbp
```
Without a client that syscall is inlined and the SIGURG sent 1st which is set to SIG_IGN just goes back to the inlined syscall in the interrupted fragment.
But w/ drmemtrace we have a tail-duplicated block for the re-entered syscall after the SIG_IGN:
```
interp: start_pc = 0x00007f08dc144117
0x00007f08dc144117 48 8b 54 24 18 mov 0x18(%rsp)[8byte] -> %rdx
0x00007f08dc14411c 48 8b 74 24 10 mov 0x10(%rsp)[8byte] -> %rsi
0x00007f08dc144121 41 89 c0 mov %eax -> %r8d
0x00007f08dc144124 8b 7c 24 08 mov 0x08(%rsp)[4byte] -> %edi
0x00007f08dc144128 31 c0 xor %eax %eax -> %eax
0x00007f08dc14412a 0f 05 syscall -> %rcx %r11
end_pc = 0x00007f08dc14412c
Exit from F2675(0x00007f08dc144117).0x00007f0898a7e526 (shared)
(block ends with syscall)
Entry into do_syscall to execute a non-ignorable system call
system call 0
main_signal_handler: thread=1684319, sig=23, xsp=0x00007f0698aaa378, retaddr=0x00007f08dcac0c0c
record_pending_signal(23) from gen routine or stub 0x00007f089886b000
Adjusting interrupted auto-restart syscall from 0x00007f089886b000 to 0x00007f089886b002
adjust_syscall_for_restart: restored xax/r0/a0 to 0
adjust_syscall_for_restart: sigreturn pc is now 0x00007f08dc14412a
main_signal_handler 23 returning now to 0x00007f089886b002
Exit from system call
post syscall: sysnum=0x0000000000000000, result=0xfffffffffffffffc (-4)
finished handling system call
receive_pending_signal
receiving signal 23
sending signal to client
app signal handler is SIG_DFL: executing default action
execute_default_action for signal 23
clearing signals_pending flag
d_r_dispatch: target = 0x00007f08dc14412a
interp: start_pc = 0x00007f08dc14412a
0x00007f08dc14412a 0f 05 syscall -> %rcx %r11
end_pc = 0x00007f08dc14412c
Exit from F2825(0x00007f08dc14412a).0x00007f0898a87c04 (shared)
(block ends with syscall)
Entry into do_syscall to execute a non-ignorable system call
system call 0
main_signal_handler: thread=1684319, sig=10, xsp=0x00007f0698aaa378, retaddr=0x00007f08dcac0c0c
```
The culprit is a recent change to raw2trace:
```
[drmemtrace]: Appending 1 instrs in bb 0x7f93dad0112a in mod 19 +0xf812a = /usr/lib/x86_64-linux-gnu/libc.so.6
0x00007f08dc14412a 0f 05 syscall -> %rcx %r11
[drmemtrace]: Found block with duplicate system call instruction. Skipping.
```
So this workaround from PR #5945 for #5934 is actually a bug b/c we do want to see dup syscalls here for auto-restart with a SIG_IGN signal.
Contributor guide
Assessment
This issue has not been assessed yet.