]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
eu-stacktrace WIP: match sysprof's handling of SIGINT
authorSerhei Makarov <serhei@serhei.io>
Mon, 24 Jun 2024 15:29:03 +0000 (11:29 -0400)
committerSerhei Makarov <serhei@serhei.io>
Mon, 24 Jun 2024 15:29:06 +0000 (11:29 -0400)
Without the signal handler, eu-stacktrace gets terminated early
by a SIGINT inherited from a parent sysprof process, and isn't
able to finish processing all the data packets.

src/stacktrace.c

index 0552f884f116c118f85c1e36bdb4f33e5716e928..fa7007f0f5e96827c734eee1724666d963e72741 100644 (file)
@@ -76,6 +76,7 @@
 #include <stdio.h>
 #include <string.h>
 #include <fcntl.h>
+#include <signal.h>
 /* #include ELFUTILS_HEADER(dwfl) */
 #include "../libdwfl/libdwflP.h"
 /* XXX: Private header needed for sysprof_find_procfile, sysprof_init_dwfl. */
@@ -132,6 +133,8 @@ static int input_fd = -1;
 static char *output_path = NULL;
 static int output_fd = -1;
 
+static int signal_count = 0;
+
 #define MODE_OPTS "none/passthru/naive"
 #define MODE_NONE 0x0
 #define MODE_PASSTHRU 0x1
@@ -428,6 +431,22 @@ sysprof_reader_getframes (SysprofReader *reader,
 
 #endif /* HAVE_SYSPROF_HEADERS */
 
+/* Required to match our signal handling with that of a sysprof parent process. */
+static void sigint_handler (int /* signo */)
+{
+  if (signal_count >= 2)
+    {
+      exit(1);
+    }
+
+  if (signal_count == 0)
+    {
+      fprintf (stderr, "%s\n", "Waiting for input to finish. Press twice more ^C to force exit.");
+    }
+
+  signal_count ++;
+}
+
 /* Main program. */
 
 static error_t
@@ -1226,6 +1245,9 @@ Utility is a work-in-progress, see README.eu-stacktrace in the source branch.")
   if (output_fd < 0)
     error (EXIT_BAD, errno, N_("Cannot open output file or FIFO '%s'"), output_path);
 
+  /* TODO: Only really needed if launched from sysprof and inheriting its signals. */
+  if (signal (SIGINT, sigint_handler) == SIG_ERR)
+    error (EXIT_BAD, errno, N_("Cannot set signal handler for SIGINT"));
 #if !(HAVE_SYSPROF_HEADERS)
   /* TODO: Should hide corresponding command line options when this is the case. */
   error (EXIT_BAD, 0, N_("Sysprof support is not available in this version."));