GDB调试实战(7)信号处理

本文介绍了如何在GDB中发送和处理信号。通过`handle`指令,可以配置GDB在接收到不同信号时的行为,如是否停止程序、打印信息及是否传递给程序处理。实战部分展示了在GDB中改变对SIGUSR1信号处理的方式,从而影响调试过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

GDB发送信号

在GDB调试状态中,可以在命令号输入signal 信号名来向程序发送信号。

输入signal按下tab会显示信号名:

(gdb) signal 
Display all 152 possibilities? (y or n)
32                   SIG108               SIG125               SIG46                SIG63                SIG80                SIG97                SIGIO                SIGSTOP
33                   SIG109               SIG126               SIG47                SIG64                SIG81                SIG98                SIGKILL              SIGSYS
34                   SIG110               SIG127               SIG48                SIG65                SIG82                SIG99                SIGLIBRT             SIGTERM
EXC_ARITHMETIC       SIG111               SIG32                SIG49                SIG66                SIG83                SIGABRT              SIGLOST              SIGTRAP
EXC_BAD_ACCESS       SIG112               SIG33                SIG50                SIG67                SIG84                SIGALRM              SIGLWP               SIGTSTP
EXC_BAD_INSTRUCTION  SIG113               SIG34                SIG51                SIG68                SIG85                SIGBUS               SIGMSG               SIGTTIN
EXC_BREAKPOINT       SIG114               SIG35                SIG52                SIG69                SIG86                SIGCANCEL            SIGPHONE             SIGTTOU
EXC_EMULATION        SIG115               SIG36                SIG53                SIG70                SIG87                SIGCHLD              SIGPIPE              SIGURG
EXC_SOFTWARE         SIG116               SIG37                SIG54                SIG71                SIG88                SIGCONT              SIGPOLL              SIGUSR1
SIG100               SIG117               SIG38                SIG55                SIG72                SIG89                SIGDANGER            SIGPRIO              SIGUSR2
SIG101               SIG118               SIG39                SIG56                SIG73                SIG90                SIGEMT               SIGPROF              SIGVTALRM
SIG102               SIG119               SIG40                SIG57                SIG74                SIG91                SIGFPE               SIGPWR               SIGWAITING
SIG103               SIG120               SIG41                SIG58                SIG75                SIG92                SIGGRANT             SIGQUIT              SIGWINCH
SIG104               SIG121               SIG42                SIG59                SIG76                SIG93                SIGHUP               SIGRETRACT           SIGWIND
SIG105               SIG122               SIG43                SIG60                SIG77                SIG94                SIGILL               SIGSAK               SIGXCPU
SIG106               SIG123               SIG44                SIG61                SIG78                SIG95                SIGINFO              SIGSEGV              SIGXFSZ
SIG107               SIG124               SIG45                SIG62                SIG79                SIG96                SIGINT               SIGSOUND        

GDB处理信号

背景:gdb的默认行为是将信号捕获,而不是传递给调试程序,我们可以通过命令配置改变这一行为

在GDB中handle指令用于设置GDB对于信号的处理,可以输入help handle来查看。

(gdb) help handle
Specify how to handle signals.
Usage: handle SIGNAL [ACTIONS]
Args are signals and actions to apply to those signals.
If no actions are specified, the current settings for the specified signals
will be displayed instead.

Symbolic signals (e.g. SIGSEGV) are recommended but numeric signals
from 1-15 are allowed for compatibility with old versions of GDB.
Numeric ranges may be specified with the form LOW-HIGH (e.g. 1-5).
The special arg "all" is recognized to mean all signals except those
used by the debugger, typically SIGTRAP and SIGINT.

Recognized actions include "stop", "nostop", "print", "noprint",
"pass", "nopass", "ignore", or "noignore".
Stop means reenter debugger if this signal happens (implies print).
Print means print a message if this signal happens.
Pass means let program see this signal; otherwise program doesn't know.
Ignore is a synonym for nopass and noignore is a synonym for pass.
Pass and Stop may be combined.

Multiple signals may be specified.  Signal numbers and signal names
may be interspersed with actions, with the actions being performed for
all signals cumulatively specified.

总结大体意思:

  • nostop
    当被调试的程序收到信号时,GDB不会停住程序的运行,但会打出消息告诉你收到这种信号。
  • stop
    当被调试的程序收到信号时,GDB会停住你的程序。
  • print
    当被调试的程序收到信号时,GDB会显示出一条信息。
  • noprint
    当被调试的程序收到信号时,GDB不会告诉你收到信号的信息。
  • pass 、noignore
    当被调试的程序收到信号时,GDB不处理信号。这表示,GDB会把这个信号交给被调试程序会处理。
  • nopass、ignore
    当被调试的程序收到信号时,GDB不会让被调试程序来处理这个信号。

上面的6项配置,其实应该划分成3组可以相互叠加的状态。即:
stop/nostop

print/noprint

pass/nopass

在GDB中可以使用info signals和info handle来查看有哪些信号在被GDB检测中和GDB对其的处理:

(gdb) info signals
Signal        Stop	Print	Pass to program	Description

SIGHUP        Yes	Yes	Yes		Hangup
SIGINT        Yes	Yes	No		Interrupt
SIGQUIT       Yes	Yes	Yes		Quit
SIGILL        Yes	Yes	Yes		Illegal instruction
SIGTRAP       Yes	Yes	No		Trace/breakpoint trap
SIGABRT       Yes	Yes	Yes		Aborted
SIGEMT        Yes	Yes	Yes		Emulation trap
SIGFPE        Yes	Yes	Yes		Arithmetic exception
SIGKILL       Yes	Yes	Yes		Killed
SIGBUS        Yes	Yes	Yes		Bus error
SIGSEGV       Yes	Yes	Yes		Segmentation fault
SIGSYS        Yes	Yes	Yes		Bad system call
SIGPIPE       Yes	Yes	Yes		Broken pipe
SIGALRM       No	No	Yes		Alarm clock
...

实战

#include <signal.h>
#include <stdio.h>

void signalHandle(int para)
{
    printf("in signal handle,signal num:%d\n", para);
}

void signalHandle2(int para)
{
    printf("in signal handle,signal num:%d\n", para);
    exit(0);
}


int main(void)
{
    signal(SIGUSR1, signalHandle);
    signal(SIGUSR2, signalHandle2);

    while(1)
    {
        printf("press any key to send a signal\n");
        getchar();
        raise(SIGUSR1);
     }

    return 0;
}

为了效果更佳明显,先运行程序,然后gdb attach到进程上,进入gdb调试模式

(gdb) c
Continuing.

Program received signal SIGUSR1, User defined signal 1.
0x00007fd1f1ec9337 in raise () from /lib64/libc.so.6
(gdb) c
Continuing.

可以发现当在程序中按下回车时,进程给自己发送了SIGUSR1信号,并且GDB捕获到该信号切停下,我们继续运行,
将GDB对SIGUSR1信号的处理设置为nostop

(gdb) handle SIGUSR1 nostop
Signal        Stop	Print	Pass to program	Description
SIGUSR1       No	Yes	Yes		User defined signal 1
(gdb) c
Continuing.

Program received signal SIGUSR1, User defined signal 1

可以发现此时只会打印,而gdb不会停下,接下来
将GDB对SIGUSR1信号的处理设置为noprint

(gdb) handle SIGUSR1 noprint
Signal        Stop	Print	Pass to program	Description
SIGUSR1       No	No	Yes		User defined signal 1
(gdb) c
Continuing

此时GDB既不会打印也不会停下。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值