Mirror of the gdb mailing list
 help / color / mirror / Atom feed
* expected behavior when a signal is sent to the ptraced child
@ 2006-05-26  2:18 Wu Zhou
  0 siblings, 0 replies; 8+ messages in thread
From: Wu Zhou @ 2006-05-26  2:18 UTC (permalink / raw)
  To: gdb

Who will get the signal, the child, or the parent? or neither?

The manual of ptrace says like this:

   While being traced, the child will stop each time a signal is delivered, 
   even if the signal is being ignored.  (The  exception  is SIGKILL,  
   which  has its usual effect.)  The parent will be notified at its next 
   wait and may inspect and modify the child process while it is stopped.
   The parent then causes the child to continue, optionally ignoring the
   delivered signal (or even  delivering a different signal instead).

My reading is that it is still the child who will get the signal, but it 
won't call its signal handler as it usually does.

It will stop instead. then the wait function of the prarent (in our case, 
GDB) will return and get the control. It can inspect the status of the 
child and know what cause the child to stop.  Then gdb can let the child
continue using PTRACE_CONT, in this it can choose to delieve the signal on 
to the child, and also ignore it, and even deliver a different signal.

If my understanding is correct. Then a follow up question is how to make 
the child not to call its signal handler and to stop instead.  The reason 
I ask this is that with one kernel, I get different result than the above
with the following test code:

linux # cat trap-handle.c
#include <sys/types.h>
#include <unistd.h>
#include "../include/asm-ppc/ptrace.h"
#include <linux/ptrace.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <linux/user.h>
#include <signal.h>
#include <errno.h>
#include <sys/ucontext.h>

#define PTRACE_SET_DEBUGREG 26
#define PTRACE_GET_DEBUGREG 25

unsigned long debug;
    struct sigaction s;

static void myhandler (unsigned int sn , siginfo_t  *si, struct ucontext_t 
*sc)
{
   unsigned int mnip;
   int i;
   
   printf("In Trap handler ************ \n");
   printf(" signal number = %d, signal errno = %d, signal code = %d, signal address = %x\n",
            si->si_signo,si->si_errno,si->si_code, si->si_addr);
}

int main()
{
    unsigned long bptaddr = 0;
    pid_t child;

    sigemptyset(&s.sa_mask);   //sa_mask = 0;
    s.sa_flags = SA_SIGINFO;
    s.sa_sigaction = (void *)myhandler;
    if (sigaction (SIGTRAP,&s,(struct sigaction *)NULL)) {
      printf("Sigaction returned error = %d\n", errno);
     exit(0);
   }


    child = fork();
    if(child == 0) {
        printf("Hi, I'm the Child \n");
        printf("child entry, waiting a little bit\n");
        sleep(5);
        printf("child pid = %x %d\n",getpid(),getpid());
        debug = getpid() - 4;
        printf("child leaving, debug = %d \n", debug);
    }
    else {

        int status;
        pid_t w;
        int rc = -100;

        ptrace(PTRACE_ATTACH, child, NULL, NULL);
        wait(NULL);
        printf("Parent now has control \n");
        printf("parent pid = %x %d\n",getpid(),getpid());
        if (rc = ptrace(PTRACE_SET_DEBUGREG,child,0,&debug))
          printf ("set debugreg return non-zero: %d\n", rc);
        else
          printf ("set debugreg return zero\n");
        ptrace(PTRACE_CONT, child, NULL, NULL);
        w =  wait(&status);
        if (w == -1) { perror("waitpid"); exit(-10); }
        if (WIFEXITED(status)) {
             printf("exited, status=%d\n", WEXITSTATUS(status));
        } else if (WIFSIGNALED(status)) {
             printf("killed by signal %d\n", WTERMSIG(status));
        } else if (WIFSTOPPED(status)) {
             printf("stopped by signal %d\n", WSTOPSIG(status));
        } else {
            printf("not sure what reason\n");
        }

        ptrace(PTRACE_DETACH, child, NULL, NULL);
        printf("debug = %d \n",debug);
    }
    return 0;
}

The output of running the executable is like this:

linux # ./trap-handle
Parent now has control
parent pid = 151a 5402
set debugreg return zero
Hi, I'm the Child
child entry, waiting a little bit
child pid = 151b 5403
In Trap handler ************
 signal number = 5, signal errno = 0, signal code = 4, signal address = 
1001110c
child leaving, debug = 5399
exited, status=0
debug = 0
# 

What I expect is the parent will at least output:

stopped by signal 5 

What is the  problem here?  Did I make something wrong?  Please correct me 
if there are anything wrong!  Thanks a lot!

Regards
- Wu Zhou


^ permalink raw reply	[flat|nested] 8+ messages in thread
* expected behavior when a signal is sent to the ptraced child
@ 2006-05-25 13:47 Wu Zhou
  0 siblings, 0 replies; 8+ messages in thread
From: Wu Zhou @ 2006-05-25 13:47 UTC (permalink / raw)
  To: gdb


Who will get the signal, the child, or the parent? or neither?

The manual of ptrace says like this:

   While being traced, the child will stop each time a signal is delivered, 
   even if the signal is being ignored.  (The  exception  is SIGKILL,  
   which  has its usual effect.)  The parent will be notified at its next 
   wait and may inspect and modify the child process while it is stopped.
   The parent then causes the child to continue, optionally ignoring the
   delivered signal (or even  delivering a different signal instead).

My reading is that it is still the child who will get the signal, but it 
won't call its signal handler as it usually does.

It will stop instead. then the wait function of the prarent (in our case, 
GDB) will return and get the control. It can inspect the status of the 
child and know what cause the child to stop.  Then gdb can let the child
continue using PTRACE_CONT, in this it can choose to delieve the signal on 
to the child, and also ignore it, and even deliver a different signal.

If my understanding is correct (if not, please correct me.  thanks.). Then 
a follow up question is how to make the child not to call its signal handler
and to stop instead.  The reason I ask this is that with one kernel, I get
different result than the above with the following test code:

[root@woodzltc ~] # cat trap-handle.c
#include <sys/types.h>
#include <unistd.h>
#include "../include/asm-ppc/ptrace.h"
#include <linux/ptrace.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <linux/user.h>
#include <signal.h>
#include <errno.h>
#include <sys/ucontext.h>

#define PTRACE_SET_DEBUGREG 26
#define PTRACE_GET_DEBUGREG 25

unsigned long debug;
    struct sigaction s;

static void myhandler (unsigned int sn , siginfo_t  *si, struct ucontext_t 
*sc)
{
   unsigned int mnip;
   int i;
   
   printf("In Trap handler ************ \n");
   printf(" signal number = %d, signal errno = %d, signal code = %d, signal address = %x\n",
            si->si_signo,si->si_errno,si->si_code, si->si_addr);
}

int main()
{
    unsigned long bptaddr = 0;
    pid_t child;

    sigemptyset(&s.sa_mask);   //sa_mask = 0;
    s.sa_flags = SA_SIGINFO;
    s.sa_sigaction = (void *)myhandler;
    if (sigaction (SIGTRAP,&s,(struct sigaction *)NULL)) {
      printf("Sigaction returned error = %d\n", errno);
     exit(0);
   }


    child = fork();
    if(child == 0) {
        printf("Hi, I'm the Child \n");
        printf("child entry, waiting a little bit\n");
        sleep(5);
        printf("child pid = %x %d\n",getpid(),getpid());
        debug = getpid() - 4;
        printf("child leaving, debug = %d \n", debug);
    }
    else {

        int status;
        pid_t w;
        int rc = -100;

        ptrace(PTRACE_ATTACH, child, NULL, NULL);
        wait(NULL);
        printf("Parent now has control \n");
        printf("parent pid = %x %d\n",getpid(),getpid());
        if (rc = ptrace(PTRACE_SET_DEBUGREG,child,0,&debug))
          printf ("set debugreg return non-zero: %d\n", rc);
        else
          printf ("set debugreg return zero\n");
        ptrace(PTRACE_CONT, child, NULL, NULL);
        w =  wait(&status);
        if (w == -1) { perror("waitpid"); exit(-10); }
        if (WIFEXITED(status)) {
             printf("exited, status=%d\n", WEXITSTATUS(status));
        } else if (WIFSIGNALED(status)) {
             printf("killed by signal %d\n", WTERMSIG(status));
        } else if (WIFSTOPPED(status)) {
             printf("stopped by signal %d\n", WSTOPSIG(status));
        } else {
            printf("not sure what reason\n");
        }

        ptrace(PTRACE_DETACH, child, NULL, NULL);
        printf("debug = %d \n",debug);
    }
    return 0;
}

The output of running the executable is like this:

[root@woodzltc ~]# ./trap-handle
Parent now has control
parent pid = 151a 5402
set debugreg return zero
Hi, I'm the Child
child entry, waiting a little bit
child pid = 151b 5403
In Trap handler ************
 signal number = 5, signal errno = 0, signal code = 4, signal address = 
1001110c
child leaving, debug = 5399
exited, status=0
debug = 0
[root@woodzltc ~]#

What I expect is the parent will at least output:

stopped by signal 5 

What is the  problem here?  Did I make something wrong?  Please correct me 
if there are anything wrong!  Thanks a lot!

Regards
- Wu Zhou


^ permalink raw reply	[flat|nested] 8+ messages in thread
* expected behavior when a signal is sent to the ptraced child
@ 2006-05-25  4:16 Wu Zhou
  2006-05-25  9:06 ` Daniel Jacobowitz
  2006-05-25 13:06 ` Andreas Schwab
  0 siblings, 2 replies; 8+ messages in thread
From: Wu Zhou @ 2006-05-25  4:16 UTC (permalink / raw)
  To: gdb


Who will get the signal, the child, or the parent? or neither?

The manual of ptrace says like this:

   While being traced, the child will stop each time a signal is delivered, 
   even if the signal is being ignored.  (The  exception  is SIGKILL,  
   which  has its usual effect.)  The parent will be notified at its next 
   wait and may inspect and modify the child process while it is stopped.
   The parent then causes the child to continue, optionally ignoring the
   delivered signal (or even  delivering a different signal instead).

My reading is that it is still the child who will get the signal, but it 
won't call its signal handler as it usually does.

It will stop instead. then the wait function of the prarent (in our case, 
GDB) will return and get the control. It can inspect the status of the 
child and know what cause the child to stop.  Then gdb can let the child
continue using PTRACE_CONT, in this it can choose to delieve the signal on 
to the child, and also ignore it, and even deliver a different signal.

If my understanding is correct. Then a follow up question is how to make 
the child not to call its signal handler and to stop instead.  The reason 
I ask this is that with one kernel, I get different result than the above
with the following test code:

linux # cat trap-handle.c
#include <sys/types.h>
#include <unistd.h>
#include "../include/asm-ppc/ptrace.h"
#include <linux/ptrace.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <linux/user.h>
#include <signal.h>
#include <errno.h>
#include <sys/ucontext.h>

#define PTRACE_SET_DEBUGREG 26
#define PTRACE_GET_DEBUGREG 25

unsigned long debug;
    struct sigaction s;

static void myhandler (unsigned int sn , siginfo_t  *si, struct ucontext_t 
*sc)
{
   unsigned int mnip;
   int i;
   
   printf("In Trap handler ************ \n");
   printf(" signal number = %d, signal errno = %d, signal code = %d, signal address = %x\n",
            si->si_signo,si->si_errno,si->si_code, si->si_addr);
}

int main()
{
    unsigned long bptaddr = 0;
    pid_t child;

    sigemptyset(&s.sa_mask);   //sa_mask = 0;
    s.sa_flags = SA_SIGINFO;
    s.sa_sigaction = (void *)myhandler;
    if (sigaction (SIGTRAP,&s,(struct sigaction *)NULL)) {
      printf("Sigaction returned error = %d\n", errno);
     exit(0);
   }


    child = fork();
    if(child == 0) {
        printf("Hi, I'm the Child \n");
        printf("child entry, waiting a little bit\n");
        sleep(5);
        printf("child pid = %x %d\n",getpid(),getpid());
        debug = getpid() - 4;
        printf("child leaving, debug = %d \n", debug);
    }
    else {

        int status;
        pid_t w;
        int rc = -100;

        ptrace(PTRACE_ATTACH, child, NULL, NULL);
        wait(NULL);
        printf("Parent now has control \n");
        printf("parent pid = %x %d\n",getpid(),getpid());
        if (rc = ptrace(PTRACE_SET_DEBUGREG,child,0,&debug))
          printf ("set debugreg return non-zero: %d\n", rc);
        else
          printf ("set debugreg return zero\n");
        ptrace(PTRACE_CONT, child, NULL, NULL);
        w =  wait(&status);
        if (w == -1) { perror("waitpid"); exit(-10); }
        if (WIFEXITED(status)) {
             printf("exited, status=%d\n", WEXITSTATUS(status));
        } else if (WIFSIGNALED(status)) {
             printf("killed by signal %d\n", WTERMSIG(status));
        } else if (WIFSTOPPED(status)) {
             printf("stopped by signal %d\n", WSTOPSIG(status));
        } else {
            printf("not sure what reason\n");
        }

        ptrace(PTRACE_DETACH, child, NULL, NULL);
        printf("debug = %d \n",debug);
    }
    return 0;
}

The output of running the executable is like this:

linux # ./trap-handle
Parent now has control
parent pid = 151a 5402
set debugreg return zero
Hi, I'm the Child
child entry, waiting a little bit
child pid = 151b 5403
In Trap handler ************
 signal number = 5, signal errno = 0, signal code = 4, signal address = 
1001110c
child leaving, debug = 5399
exited, status=0
debug = 0
# 

What I expect is the parent will at least output:

stopped by signal 5 

What is the  problem here?  Did I make something wrong?  Please correct me 
if there are anything wrong!  Thanks a lot!

Regards
- Wu Zhou


^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2006-05-26  2:18 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-05-26  2:18 expected behavior when a signal is sent to the ptraced child Wu Zhou
  -- strict thread matches above, loose matches on Subject: below --
2006-05-25 13:47 Wu Zhou
2006-05-25  4:16 Wu Zhou
2006-05-25  9:06 ` Daniel Jacobowitz
2006-05-25 12:07   ` Wu Zhou
2006-05-25 13:06 ` Andreas Schwab
2006-05-25 19:37   ` Daniel Jacobowitz
2006-05-26 20:57     ` Wu Zhou

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox