Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DR does not handle interrupted system calls properly #1145

Closed
derekbruening opened this issue Nov 28, 2014 · 1 comment
Closed

DR does not handle interrupted system calls properly #1145

derekbruening opened this issue Nov 28, 2014 · 1 comment

Comments

@derekbruening
Copy link
Contributor

derekbruening commented Nov 28, 2014

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 &#37;d &#37;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 &#37;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

@derekbruening
Copy link
Contributor Author

From derek.br...@gmail.com on July 11, 2013 16:14:41

This issue was closed by revision r2169 .

Status: Fixed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant