From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 1925 invoked by alias); 25 May 2006 12:07:35 -0000 Received: (qmail 1760 invoked by uid 22791); 25 May 2006 12:07:33 -0000 X-Spam-Check-By: sourceware.org Received: from ausmtp04.au.ibm.com (HELO ausmtp04.au.ibm.com) (202.81.18.152) by sourceware.org (qpsmtpd/0.31) with ESMTP; Thu, 25 May 2006 12:06:59 +0000 Received: from sd0208e0.au.ibm.com (d23rh904.au.ibm.com [202.81.18.202]) by ausmtp04.au.ibm.com (8.13.6/8.13.5) with ESMTP id k4P1QQcJ231382 for ; Thu, 25 May 2006 11:26:26 +1000 Received: from d23av04.au.ibm.com (d23av04.au.ibm.com [9.190.250.237]) by sd0208e0.au.ibm.com (8.12.10/NCO/VER6.8) with ESMTP id k4P1RCEf228470 for ; Thu, 25 May 2006 11:27:12 +1000 Received: from d23av04.au.ibm.com (loopback [127.0.0.1]) by d23av04.au.ibm.com (8.12.11.20060308/8.13.3) with ESMTP id k4P1Nqn7025437 for ; Thu, 25 May 2006 11:23:52 +1000 Received: from [9.181.133.48] ([9.181.133.48]) by d23av04.au.ibm.com (8.12.11.20060308/8.12.11) with ESMTP id k4P1No5I025311 for ; Thu, 25 May 2006 11:23:51 +1000 Date: Thu, 25 May 2006 13:47:00 -0000 From: Wu Zhou To: gdb@sources.redhat.com Subject: expected behavior when a signal is sent to the ptraced child Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII X-IsSubscribed: yes Mailing-List: contact gdb-help@sourceware.org; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-owner@sourceware.org X-SW-Source: 2006-05/txt/msg00369.txt.bz2 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 #include #include "../include/asm-ppc/ptrace.h" #include #include #include #include #include #include #include #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