信号(7)手册页说, SIGKILL不能被捕获,阻塞或忽略。 但是我刚才注意到,在使用GDB连接到一个进程后,我不能再发送SIGKILL到这个进程(同样,其他的信号也不能传送)。 但是在我分离并退出GDB之后, SIGKILL像往常一样交付。
在我看来,GDB在连接时阻止了该信号(代表tracee),并在分离时解除阻塞。 但是, ptrace(2)手册页说:
在跟踪的过程中,即使信号被忽略,每次信号传递时Tracee也会停止。 ( SIGKILL是一个例外,具有其通常的效果。)
那为什么这样呢? GDB使用什么技巧?
这是一个示范的简单例子:
testing程序
#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...
仅供参考,我使用的是CentOS-6u3,而uname -r
结果是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)
。 一台旧机器…
任何想法将不胜感激;-)
$ ##### in shell 1 ##### $ gdb (gdb) attach ${pid} (gdb)
问题是,一旦GDB连接到${pid}
,低级(被调试)进程不再运行 – 它被停止 。
直到它继续(使用(gdb) continue
命令),或者它不再被跟踪( (gdb) detach
或quit
),内核将不会执行任何操作 。
如果你发出continue
( kill -QUIT
之前或之后),你会看到:
(gdb) c Continuing.
kill -QUIT $pid
在另一个shell中执行:
Program received signal SIGQUIT, Quit. main (argc=1, argv=0x7ffdcc9c1518) at tc:35 35 } (gdb) c Continuing. Received signal: 3 signal originate from pid[123419]
kill -KILL
在另一个窗口中执行:
Program terminated with signal SIGKILL, Killed. The program no longer exists. (gdb)