如何使用GDB通过信号处理调试代码?

时间:2014-07-05 23:02:59

标签: gdb

我在调试中运行代码。一旦父进程收到一个信号,调试器就会在步进时显示我在父处理程序代码中。但从那时起,我无法控制GDB。当我点击“继续”时它会输入一些文件并停止并显示以下消息:

Program received signal SIGTRAP, Trace/breakpoint trap.
_dl_runtime_resolve () at ../sysdeps/x86_64/dl-trampoline.S:34
34  ../sysdeps/x86_64/dl-trampoline.S: No such file or directory.
(gdb) continue

当我尝试继续时,它会重复使用新文件。

show follow-fork-mode的输出和show forkch-on-fork

(gdb) b 78
Breakpoint 1 at 0x400bba: file main.c, line 78.
(gdb) run
Starting program: /home/samkit/Posix_Programming/unix_Simple_prodcon_con_prob/main 
Child sending signal

Breakpoint 1, main (argc=1, argv=0x7fffffffdf48) at main.c:79

79      if(cpid==0){

(gdb) show follow-fork-mode

Debugger response to a program call of fork or vfork is "parent".

(gdb) show detach-on-fork

Whether gdb will detach the child of a fork is on.

(gdb) 

还尝试在GDB中切换到子进程,在第78行设置断点然后运行。子进程向父进程发送信号并从父进程接收SIGUSR2。因此进入自己的处理程序。之后GDB无法返回(类似于上面)以下是输出:

(gdb) set follow-fork-mode child
(gdb) set detach-on-fork on
(gdb) b 78
Breakpoint 1 at 0x400bba: file main.c, line 78.
(gdb) run
Starting program: /home/samkit/Posix_Programming/unix_Simple_prodcon_con_prob/main 
[New process 31109]
[Switching to process 31109]

Breakpoint 1, main (argc=1, argv=0x7fffffffdf48) at main.c:79
79      if(cpid==0){
(gdb) next
83          if((child_sm_id = shmget(key,size*sizeof(char),0))==-1){    // Allocate shared memory
(gdb) next
87          if((child_sm_ptr = shmat(child_sm_id,NULL,0)) == (void *)-1){       // Attach shared memory to your address space
(gdb) next
 95             printf("Child sending signal\n");
(gdb) next

Child sending signal
96              kill(getppid(),SIGUSR1);
(gdb) next
Received Signal 10
Sending signal

Program received signal SIGUSR2, User defined signal 2.
0x00007ffff7a4b267 in kill () at ../sysdeps/unix/syscall-template.S:81
81  ../sysdeps/unix/syscall-template.S: No such file or directory.
(gdb) next
childHandler (sig=0) at main.c:25
25  void childHandler(int sig){
(gdb) next
26      printf("Child received Signal %d\n",sig);
(gdb) next

Program received signal SIGTRAP, Trace/breakpoint trap.
0x00000000004006e6 in printf@plt ()
(gdb) next
Single stepping until exit from function printf@plt,
which has no line number information.
0x00000000004006b0 in ?? ()
(gdb) next
Cannot find bounds of current function
(gdb) 

我也尝试过继续,但我认为自从GDB看到TRAP后,如果我继续尝试,它会一次又一次地重新执行TRAP。

(gdb) continue
Continuing.

Program received signal SIGTRAP, Trace/breakpoint trap.
0x00000000004006b6 in ?? ()
(gdb) ccontinue
Undefined command: "ccontinue".  Try "help".
(gdb) continue
Continuing.

Program received signal SIGTRAP, Trace/breakpoint trap.
_dl_runtime_resolve () at ../sysdeps/x86_64/dl-trampoline.S:34
34  ../sysdeps/x86_64/dl-trampoline.S: No such file or directory.
(gdb) continue
Continuing.

现在我的问题:

Q1)如何让GDB继续执行? Q2)我有2个进程。如果我在fork之后放置一个断点并执行信息线程,它会显示1个进程和1个进程。它不应该显示2个过程吗?

代码:

# include  <signal.h>
# include <stdio.h>
# include <sys/types.h>
# include <sys/fcntl.h>
# include <sys/shm.h>
# include <sys/ipc.h>
# include <unistd.h>
# include <sys/wait.h>
#include <string.h>
#include <stdlib.h>

#define BUFF_SIZE 1024

struct smbuffer{
 char buffer[1024];
 int count;
};

void parentHandler(int sig){
   printf("Received Signal %d\n",sig);
 }

void childHandler(int sig){
   printf("Child received Signal %d\n",sig);
}

int main( int argc, char* argv[] ) {
/* Child related attributes */
pid_t cpid;
int status;
int retval;

/* Shared memory initialization */
int sm_id;
struct smbuffer *sm_ptr;
key_t key = 1100;
int size = BUFF_SIZE;


if((sm_id = shmget(key , size * sizeof(char) , 0666|IPC_CREAT))== -1){  // Allocate shared memory

    perror("SHMGET Failed : \n");
    exit(1);
}

if((sm_ptr = shmat(sm_id,NULL,0))==(void *)-1){ // Attach shared memory to your address space

    perror("SHMAT Failed : \n");
    exit(1);
}

// Intilitialing Signals and handler
struct sigaction childold;  
struct sigaction childnew;
childnew.sa_handler = childHandler;
sigset_t childmask ;
sigemptyset(&childmask);
childnew.sa_mask = childmask;
childnew.sa_flags = 0;
sigaction(SIGUSR2,&childnew,&childold);

// Intilitialing Signals and handler
struct sigaction parentold; 
struct sigaction parentnew;
parentnew.sa_handler = parentHandler;
sigset_t parentmask ;
sigemptyset(&parentmask);
parentnew.sa_mask = parentmask;
parentnew.sa_flags = 0;
sigaction(SIGUSR1,&parentnew,&parentold);


if((cpid = fork())== -1){
    perror("Fork Failed :\n");
}

if(cpid==0){
    /* Child code */
    struct smbuffer *child_sm_ptr; 
    int child_sm_id ;
    if((child_sm_id = shmget(key,size*sizeof(char),0))==-1){    // Allocate shared memory
        perror("Child shmget failed :\n");
        exit(2);
    }   
    if((child_sm_ptr = shmat(child_sm_id,NULL,0)) == (void *)-1){       // Attach shared memory to your address space
        perror("Child shmat failed :\n");
        exit(2);
    }


    // Signal parent and wait for signal from parent. Loop 
    while(1){
        printf("Child sending signal\n");
        kill(getppid(),SIGUSR1);
        sigsuspend(&childmask);
        sleep(1);
    }

    if(shmdt(child_sm_ptr)==-1){            // De-attach shared memory
        perror("Child shmdt failed :\n");
        exit(2);
    }

    printf("Child exit\n");
    return 0;
}

else{
    /* Parent code */

    // Wait for child signal and signal child. Loop 
    while(1){   
        sigsuspend(&parentmask);
        printf("Sending signal\n");
        kill(cpid,SIGUSR2);
        sleep(1);
    }
}

if(shmdt(sm_ptr)==-1){          // De-attach shared memory
    perror("SHMDT failed :\n");
    exit(1);
}

// Free shared memory
    if((shmctl(sm_id, IPC_RMID, NULL)) == -1){
        perror("Shmctl failed \n");
            exit(1);
    }

printf("End of code\n");
return 0;

} // End of main

0 个答案:

没有答案