]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
coredumpctl: propagate SIGTERM to the debugger process
authorFrantisek Sumsal <frantisek@sumsal.cz>
Tue, 7 Nov 2023 11:06:02 +0000 (12:06 +0100)
committerLuca Boccassi <luca.boccassi@gmail.com>
Tue, 7 Nov 2023 15:41:33 +0000 (15:41 +0000)
If we're waiting for the debugger process to exit and receive SIGTERM,
propagate it to all processes in our process group, including the
debugger, so we can follow it up with a proper cleanup.

Resolves: #28772

src/coredump/coredumpctl.c

index 2245b350e4342e0d0288304bb8074ef3f0a1482e..84d45316d4094ffd339afcfa4c80ead864d75f16 100644 (file)
@@ -1153,10 +1153,24 @@ static int dump_core(int argc, char **argv, void *userdata) {
         return 0;
 }
 
+static void sigterm_handler(int signal, siginfo_t *info, void *ucontext) {
+        assert(signal == SIGTERM);
+        assert(info);
+
+        /* If the sender is not us, propagate the signal to all processes in
+         * the same process group */
+        if (pid_is_valid(info->si_pid) && info->si_pid != getpid_cached())
+                (void) kill(0, signal);
+}
+
 static int run_debug(int argc, char **argv, void *userdata) {
         _cleanup_(sd_journal_closep) sd_journal *j = NULL;
         _cleanup_free_ char *exe = NULL, *path = NULL;
         _cleanup_strv_free_ char **debugger_call = NULL;
+        struct sigaction sa = {
+                .sa_sigaction = sigterm_handler,
+                .sa_flags = SA_SIGINFO,
+        };
         bool unlink_path = false;
         const char *data, *fork_name;
         size_t len;
@@ -1250,6 +1264,7 @@ static int run_debug(int argc, char **argv, void *userdata) {
 
         /* Don't interfere with gdb and its handling of SIGINT. */
         (void) ignore_signals(SIGINT);
+        (void) sigaction(SIGTERM, &sa, NULL);
 
         fork_name = strjoina("(", debugger_call[0], ")");
 
@@ -1266,7 +1281,7 @@ static int run_debug(int argc, char **argv, void *userdata) {
         r = wait_for_terminate_and_check(debugger_call[0], pid, WAIT_LOG_ABNORMAL);
 
 finish:
-        (void) default_signals(SIGINT);
+        (void) default_signals(SIGINT, SIGTERM);
 
         if (unlink_path) {
                 log_debug("Removed temporary file %s", path);