strace / strace

strace is a diagnostic, debugging and instructional userspace utility for Linux
Other
2.17k stars 425 forks source link

strace does not pass SIGTSTP signals to the program #96

Closed bhaible closed 5 years ago

bhaible commented 5 years ago

When a program is run in a terminal, and the user presses Ctrl-Z (the SUSP key), the program receives a SIGTSTP signal. The default action is to stop the program.

When a program is, however, run under strace in a terminal, and the user presses Ctrl-Z, the program does not receive a SIGTSTP signal. Most probably it receives a SIGSTOP signal (for which no signal handlers can be installed).

How to reproduce: I'm using strace 4.11 on Ubuntu 16.04. Here is a program sigtstp-example.c.

#include <signal.h>
#include <string.h>
#include <unistd.h>

void sigtstp_handler (int sig)
{
  char message[] = "in sigtstp_handler\n";
  int ret = write (2, message, strlen (message));
  (void)ret;
}

int main ()
{
  struct sigaction action;
  action.sa_handler = sigtstp_handler;
  action.sa_flags = SA_NODEFER;
  sigemptyset (&action.sa_mask);
  sigaction (SIGTSTP, &action, NULL);

  for (;;)
    sleep (1);
}
$ gcc -O -Wall sigtstp-example.c
$ ./a.out 
^Zin sigtstp_handler
^Zin sigtstp_handler
^C
$ strace -o /tmp/log ./a.out 
^Z
[1]+  Angehalten              strace -o /tmp/log ./a.out
$ fg 1
strace -o /tmp/log ./a.out
^C
$ grep SIGTSTP /tmp/log
rt_sigaction(SIGTSTP, {0x400676, [], SA_RESTORER|SA_NODEFER, 0x7f25502634b0}, NULL, 8) = 0

You can see that, when run under strace:

I'm debugging a program that makes use of a SIGTSTP handler, and it took me a real while to understand why it is malfunctioning under strace.

ldv-alt commented 5 years ago

strace has an option for this case, try

$ strace -I 4 -o /tmp/log ./a.out
bhaible commented 5 years ago

Yes, with -I 4 it works as expected.

Why is -I 4 not the default?

ldv-alt commented 5 years ago

Traditional defaults are often OK, but sometimes they are not, so -I option was introduced in strace 4.7 to control strace interactiveness.

There must be an inherent bug or a massive shift in use patterns to change a traditional default behavior like this.

-I option is documented in strace manual page. If you don't find the documentation appropriate enough, patches are always welcome.

bhaible commented 5 years ago

Answering my own question: Why is -I 4 not the default?

I tried to use it for a while, and for processes that being put into the background, it operates worse than the default mode.

ldv-alt commented 5 years ago

Try -D -I4.

bhaible commented 5 years ago

Yes, -D -I4 produces a good behaviour regarding processes that catch SIGTSTP and get put into the background/foreground. Why is this not the default?

> There must be an inherent bug or a massive shift in use patterns to change a traditional default behavior like this. Sending a process SIGSTOP instead of SIGTSTP is an inherent bug.

bhaible commented 5 years ago

Thanks for your help! Using a well-working strace is much more comfortable than debugging through log statements.

ldv-alt commented 5 years ago

Thanks, I'm also inclined to think -I4 would be better default for -D than the current one.

ldv-alt commented 5 years ago

It's less obvious with making -D the default: the current strace behavior to wait for all processes including those created for piped output (-o option) is useful only if -D option is not used.