为什么GDB在附加到tracee时会屏蔽tracee的SIGKILL

时间:2017-11-26 09:01:00

标签: linux gdb signals ptrace

signal(7)手册页说明无法捕获,阻止或忽略 SIGKILL 。但我刚观察到,在使用GDB附加到进程后,我无法再将 SIGKILL 发送到该进程(类似地,其他信号也无法传递)。但在我分离并退出GDB之后, SIGKILL 照常交付。

在我看来,GDB在附加时阻止了该信号(代表tracee),并在分离时解锁了它。但是,ptrace(2)手册页说:

  

在跟踪时,即使信号被忽略,每次传送信号时,tracee都会停止。 (例外情况是 SIGKILL ,它有其通常的效果。)

那为什么它会这样呢? GDB使用了哪些技巧?

这是一个简单的演示示例:

1。测试程序

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#include <string.h>

/* Simple error handling functions */

#define handle_error_en(en, msg) \
    do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)

struct sigaction act;

void sighandler(int signum, siginfo_t *info, void *ptr) {
    printf("Received signal: %d\n", signum);
    printf("signal originate from pid[%d]\n", info->si_pid);
}

int
main(int argc, char *argv[])
{
    printf("Pid of the current process: %d\n", getpid());

    memset(&act, 0, sizeof(act));

    act.sa_sigaction = sighandler;
    act.sa_flags = SA_SIGINFO;

    sigaction(SIGQUIT, &act, NULL);

    while(1) {
        ;
    }

    return 0;
}

如果您尝试使用 SIGKILL (即使用kill -KILL ${pid})杀死此程序,它将按预期死亡。如果您尝试发送 SIGQUIT (即使用kill -QUIT ${pid}),那么 printf 语句将按预期执行。但是,如果您在发送信号之前已将其与GDB连接,则不会发生任何事情:

$ ##### in shell 1 #####
$ gdb
(gdb) attach ${pid}
(gdb)

/ *现在gdb已成功附加,在另一个shell中:* /

$ #### in shell 2 ####
$ kill -QUIT ${pid}    # nothing happen
$ kill -KILL ${pid}    # again, nothing happen!

/ *现在gdb分离了* /

##### in shell 1 ####
(gdb) quit

/ *该过程将收到 SIGKILL * /

##### in shell 2 ####
$ Killed    # the tracee receive **SIGKILL** eventually...

仅供参考,我在uname -r使用CentOS-6u3和2.6.32_1-16-0-0结果。我的GDB版本是:GNU gdb (GDB) Red Hat Enterprise Linux (7.2-56.el6),我的GCC版本是:gcc (GCC) 3.4.6 20060404 (Red Hat 3.4.6-19.el6)。一台旧机......

任何想法都将受到赞赏; - )

0 个答案:

没有答案