Why can GDB mask tracee's SIGKILL after attaching
Yubin Ruan
ablacktshirt@gmail.com
Mon Nov 27 02:23:00 GMT 2017
2017-11-26 17:07 GMT+08:00 Yubin Ruan <ablacktshirt@gmail.com>:
> The signal(7) man page says that **SIGKILL** cannot be caught,
> blocked, or ignored. But I just observed that after attaching to a
> process with GDB, I can no longer send **SIGKILL** to that process
> (similarly, other signal cannot be delivered either). But after I
> detached and quit GDB, **SIGKILL** is delivered as usual (and the
> process get killed, eventually).
>
> It seems to me that GDB has blocked that signal (on behalf of the
> tracee) when attaching, and unblocked it when detaching. However, the
> ptrace(2) man page says:
>
> While being traced, the tracee will stop each time a signal is delivered,
> even if the signal is being ignored. (An exception is **SIGKILL**, which
> has its usual effect.)
>
> So why does it behave this way? Is there anything wrong with the man
> page or is GDB using any kernel trick?
>
> Here is an trivial example for demonstration:
>
> #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;
> }
>
> If you try to kill this program using **SIGKILL** (i.e., using "kill
> -KILL ${pid}"), it will die as expected. If you try to send it
> **SIGQUIT** (i.e., using "kill -QUIT ${pid}"), those "printf"
> statements get executed, as expected. However, if you have attached it
> with GDB before sending it signal, nothing will happen:
>
> $ ##### in shell 1 #####
> $ gdb
> (gdb) attach ${pid}
> (gdb)
>
> /* now that gdb has attached successfully, in another shell: */
>
> $ #### in shell 2 ####
> $ kill -QUIT ${pid} # nothing happen
> $ kill -KILL ${pid} # again, nothing happen!
>
> /* now gdb detached */
>
> ##### in shell 1 ####
> (gdb) quit
>
> /* the process will receive **SIGKILL** */
>
> ##### in shell 2 ####
> $ Killed # the tracee receive **SIGKILL** eventually...
It seems that a process cannot receive any signal when stopped...
Yubin
More information about the Gdb
mailing list