DR does not handle interrupted system calls properly
From bruen...@google.com on April 16, 2013 14:52:00
Today, DR does not set SA_RESTART when it installs its own signal handlers, regardless of what the app requested. Plus, it sends signals for its own purposes that might interrupt a system call (SIGUSR1 for thread suspension; SIGILL for nudges).
These two factors combine to mean that an app running under DR might have different system call restart behavior than it would natively. The app might use signal(), or use sigaction() with SA_RESTART, and expect something like read() to be auto-restarted. Yet under DR the syscall will instead return EINTR, which the app wouldn't expect in this case.
This is easily illustrated:
# cat eintr.c
#include <stdio.h>
int
main(int argc, char **argv)
{
char buf[16];
int res = read(stdin->_fileno, buf, 2);
if (res < 0)
perror("error during read");
else
printf("got %d %c\n", res, buf[0]);
return 0;
}
# gcc -o eintr eintr.c -g
# ./eintr
In another shell:
# kill -s SIGURG `pgrep eintr`
Natively, nothing happens and the app keeps waiting for input. Under DR:
# /work/dr/git/exports/bin64/drrun -debug -- ./eintr
<Starting application /work/dr/test/eintr (6670)>
<Initial options = -code_api -stack_size 56K -max_elide_jmp 0 -max_elide_call 0 -no_inline_ignored_syscalls -native_exec_default_list '' -no_native_exec_managed_code -no_indcall2direct >
error during read: Interrupted system call
got -1
<Stopping application /work/dr/test/eintr (6670)>
I picked SIGURG because its default behavior is ignore: I could pick a default-terminate signal and have the app install a handler via signal() and we'd have a similar effect:
Add to the app:
#include <signal.h>
void handler(int sig) { printf("in handler %d\n", sig); }
signal(SIGUSR1, handler);
Natively:
# ./eintr
in handler 10
<keeps waiting>
DR:
# /work/dr/git/exports/bin64/drrun -debug -- ./eintr
<Starting application /work/dr/test/eintr (6709)>
<Initial options = -code_api -stack_size 56K -max_elide_jmp 0 -max_elide_call 0 -no_inline_ignored_syscalls -native_exec_default_list '' -no_native_exec_managed_code -no_indcall2direct >
in handler 10
error during read: Interrupted system call
<Stopping application /work/dr/test/eintr (6709)>
Original issue: http://code.google.com/p/dynamorio/issues/detail?id=1145