Hello, I've been running into a problem where a child running under strace does not stop when it reaches raise(SIGSTOP). This was unexpected at first... The attached program [strace-test.c] demoes this behavior, and runs differently when being traced.
$ ./strace-test
Parent: sleeping for a while...
Parent: SUCCESS. Child killed, sig = 9
$ strace -f ./strace-test 2>/dev/null
Parent: sleeping for a while...
Child: FAIL.
Parent: FAIL. Child exited, status = 1
After quite some experimentation, I came to this, in the manual page:
A traced process ignores SIGSTOP except on SVR4 platforms.
which I understand is a limitation coming from the way ptrace() works
under Linux?
So, I tried with SIGTSTP instead. Again, it seems a child process being
traced will not hang when doing a raise(SIGTSTP) [the signal to use can
be #defined in strace-test.c]
I've tried with
Linux hostname 2.6.26-2-amd64 #1 SMP Tue Jan 25 05:59:43 UTC 2011 x86_64
GNU/Linux
and Debian-provided "strace -- version 4.5.17",
as well as
Linux hostname 3.0.4 #1 SMP Tue Aug 30 12:55:46 EEST 2011 i686 GNU/Linux
with latest strace, compiled from git master, commit
e73a89d99921f7b9dc3f1350a4eb97c7fdc6032a.
To summarize, is there anything I can do to have straced processes stop
on reception of a signal? If not, is it a matter of the way ptrace()
works? Then perhaps the manpage should not mention SIGSTOP only.
Thank you,
Vangelis.
--
Vangelis Koukis
[email protected]
OpenPGP public key ID:
pub 1024D/1D038E97 2003-07-13 Vangelis Koukis <[email protected]>
Key fingerprint = C5CD E02E 2C78 7C10 8A00 53D8 FBFC 3799 1D03 8E97
Our greatest glory is not in never failing,
but in rising up every time we fail.
-- Ralph Waldo Emerson
/*
* strace-test.c
*
* Make sure everything works OK when strace'ing
* a program using fork() and signals.
*
* Usage:
*
* strace -f ./strace-test 2>/dev/null
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>
#include <signal.h>
#include <sys/wait.h>
#define STOP_SIGNAL SIGTSTP
int main(int argc, char *argv[])
{
int status;
pid_t p, waitp;
p = fork();
if (p < 0) {
perror("fork");
exit(1);
}
if (p == 0) {
raise(STOP_SIGNAL);
/* Should never reach this point */
printf("Child: FAIL.\n");
exit(1);
}
/*
* Father sleeps for a while and kills the child.
* The child should be alive when the father wakes.
*/
printf("Parent: sleeping for a while...\n");
sleep(2);
if (kill(p, SIGKILL) < 0) {
perror("kill");
exit(1);
}
waitp = wait(&status);
assert(p == waitp);
if (WIFEXITED(status)) {
printf("Parent: FAIL. Child exited, status = %d\n",
WEXITSTATUS(status));
exit(1);
}
if (!WIFSIGNALED(status)) {
printf("Parent: FAIL. Child not signaled?\n");
exit(1);
}
printf("Parent: SUCCESS. Child killed, sig = %d\n",
WTERMSIG(status));
return 0;
}
signature.asc
Description: Digital signature
------------------------------------------------------------------------------ Keep Your Developer Skills Current with LearnDevNow! The most comprehensive online learning library for Microsoft developers is just $99.99! Visual Studio, SharePoint, SQL - plus HTML5, CSS3, MVC3, Metro Style Apps, more. Free future releases when you subscribe now! http://p.sf.net/sfu/learndevnow-d2d
_______________________________________________ Strace-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/strace-devel
