如何使用GDB调试带有信号处理的代码?

如何使用GDB调试带有信号处理的代码?,gdb,Gdb,我正在调试下面的代码。一旦父进程接收到一个信号,调试器就会在介入时显示我在父处理程序代码中。但从那以后,我就无法控制GDB了。当我点击continue(继续)时,它会进入某个文件并停止,并显示以下消息: Program received signal SIGTRAP, Trace/breakpoint trap. _dl_runtime_resolve () at ../sysdeps/x86_64/dl-trampoline.S:34 34 ../sysdeps/x86_64/dl-tram

我正在调试下面的代码。一旦父进程接收到一个信号,调试器就会在介入时显示我在父处理程序代码中。但从那以后,我就无法控制GDB了。当我点击continue(继续)时,它会进入某个文件并停止,并显示以下消息:

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
当我尝试继续时,它会重复出现新文件

显示跟随分叉模式和显示分叉分离的输出

(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看到了一个陷阱,如果我尝试继续,它就会一次又一次地重新执行这个陷阱

(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实际继续执行? 问题2)我有2个进程。如果我在fork和do info线程之后放置一个断点,它将显示1个进程和1个线程。它不应该显示两个过程吗

代码:

#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#定义BUFF_大小1024
结构smbuffer{
字符缓冲区[1024];
整数计数;
};
无效父处理程序(int-sig){
printf(“接收到的信号%d\n”,sig);
}
void childHandler(int-sig){
printf(“子接收信号%d\n”,sig);
}
int main(int argc,char*argv[]){
/*子相关属性*/
pid_t cpid;
智力状态;
内部检索;
/*共享内存初始化*/
int sm_id;
结构smbuffer*sm_ptr;
键=1100;
int size=BUFF_size;
如果((sm|u id=shmget(key,size*sizeof(char),0666 | IPC|u CREAT))=-1){//分配共享内存
perror(“SHMGET失败:\n”);
出口(1);
}
如果((sm_ptr=shmat(sm_id,NULL,0))==(void*)-1{//将共享内存附加到地址空间
perror(“SHMAT失败:\n”);
出口(1);
}
//初始化信号和处理器
结构sigaction-childold;
struct-sigaction-childnew;
childnew.sa_handler=childHandler;
sigset\u t儿童面具;
SIGEPTYSET(&childmask);
childnew.sa_mask=childmask;
childnew.sa_标志=0;
sigaction(SIGUSR2、childnew和childold);
//初始化信号和处理器
结构sigaction parentold;
结构sigaction parentnew;
parentnew.sa_handler=parentHandler;
sigset\u t父掩码;
sigeptypyset(和parentmask);
parentnew.sa_mask=parentmask;
parentnew.sa_标志=0;
sigaction(SIGUSR1、parentnew和parentold);
如果((cpid=fork())=-1){
perror(“Fork失败:\n”);
}
如果(cpid==0){
/*子代码*/
结构smbuffer*child\u smu ptr;
int child_sm_id;
如果((child_sm_id=shmget(key,size*sizeof(char),0))==1{//分配共享内存
perror(“子shmget失败:\n”);
出口(2);
}   
如果((child_sm_ptr=shmat(child_sm_id,NULL,0))==(void*)-1){//将共享内存附加到地址空间
perror(“子shmat失败:\n”);
出口(2);
}
//向父循环发送信号并等待来自父循环的信号
而(1){
printf(“子发送信号”);
kill(getppid(),SIGUSR1);
sigsupspend(和childmask);
睡眠(1);
}
if(shmdt(child_sm_ptr)==-1){//deattach共享内存
perror(“子shmdt失败:\n”);
出口(2);
}
printf(“子出口”);
返回0;
}
否则{
/*父代码*/
//等待子信号和子信号。循环
而第(1)款{
sigsupspend(和parentmask);
printf(“发送信号”);
杀死(cpid,SIGUSR2);
睡眠(1);
}
}
if(shmdt(sm_ptr)==-1){//deattach共享内存
perror(“SHMDT失败:\n”);
出口(1);
}
//空闲共享内存
if((shmctl(sm_id,IPC_RMID,NULL))=-1){
perror(“Shmctl失败\n”);
出口(1);
}
printf(“代码结束\n”);
返回0;
}//主管道末端

你能把
显示跟随fork模式
在fork上显示分离
的输出包括在内吗?@MarkPlotnick我已经用outputsAnswer将帖子更新为Q2:当
在fork上分离
打开时(默认),gdb将不控制子线程,
信息线程
将只显示父线程。如果在目标分叉之前在gdb中执行
set detach on fork off
info threads
将显示这两个进程。我无法重现您在Q1中遇到的问题,但gdb会话中的main.c:79行实际上是您提供的代码中的第64行,所以可能还有一些我们没有看到的导致问题的额外代码。这可能是gdb中的错误
handle SIGTRAP nostop
handle SIGTRAP noprint
将让您更进一步,但这可能会影响gdb执行断点的能力。非常感谢@MarkPlotnick!!我至少可以继续执行noprint和nostop:)。非常感谢您的时间和精彩的回复。我学到了很多!
# 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