Skip to content
GitLab
Projects Groups Snippets
  • /
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in / Register
  • D dynamorio
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
  • Issues 1,467
    • Issues 1,467
    • List
    • Boards
    • Service Desk
    • Milestones
  • Merge requests 44
    • Merge requests 44
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
  • Deployments
    • Deployments
    • Environments
    • Releases
  • Packages and registries
    • Packages and registries
    • Package Registry
    • Infrastructure Registry
  • Monitor
    • Monitor
    • Incidents
  • Analytics
    • Analytics
    • Value stream
    • CI/CD
    • Repository
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • DynamoRIO
  • dynamorio
  • Issues
  • #1145
Closed
Open
Issue created Nov 28, 2014 by Derek Bruening@derekbrueningContributor

DR does not handle interrupted system calls properly

From [email protected] 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

Assignee
Assign to
Time tracking