]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
eu-stacktrace WIP: simple passthrough for sysprof
authorSerhei Makarov <serhei@serhei.io>
Tue, 2 May 2023 20:01:41 +0000 (16:01 -0400)
committerSerhei Makarov <serhei@serhei.io>
Tue, 2 May 2023 20:01:41 +0000 (16:01 -0400)
Works with the sysprof serhei/samples-via-fifo patchset [1].

Example usage:
- mkfifo /tmp/test.fifo
- eu-stacktrace --input=/tmp/test.fifo --output=test.syscap &
- sysprof-cli --use-fifo=/tmp/test.fifo test.syscap

[1]: https://git.sr.ht/~serhei/sysprof-experiments/log/serhei/samples-via-fifo

src/stacktrace.c

index 485ddd7fbe1ef8c1e134ac95b2e8e9ede0ce4441..e09331f156f2159f41de8335e775c4be91ecaaa1 100644 (file)
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <config.h>
+#include <assert.h>
 #include <argp.h>
 #include <stdio.h>
 #include <string.h>
+#include <fcntl.h>
 
 #include <system.h>
 
 /* TODO: Make optional through configury.  The #ifdefs are included
-   already so we don't miss any code that needs to be controlled with
-   this option. */
+   now so we don't miss any code that needs to be controlled with this
+   option. */
 #define HAVE_SYSPROF_4_HEADERS
 #ifdef HAVE_SYSPROF_4_HEADERS
 #include <sysprof-4/sysprof-capture-types.h>
 #endif
 
 static char *input_path = NULL;
+static int input_fd = -1;
 static char *output_path = NULL;
+static int output_fd = -1;
+
+static size_t passthru_buffer_len = 0;
+static char *passthru_buffer = NULL;
 
 #define MODE_OPTS "none/passthru"
 #define MODE_NONE 0x0
@@ -45,10 +52,10 @@ static int processing_mode;
 #define FORMAT_SYSPROF 0x2
 static int input_format;
 
-/* Program exit codes. All samples processed without any errors is
-   GOOD.  Some non-fatal errors during processing is an ERROR.  A fatal
-   error or no samples processed at all is BAD.  A command line USAGE
-   exit is generated by argp_error. */
+/* Program exit codes.  All samples processed without any errors is
+   GOOD.  Some non-fatal errors during processing is an ERROR.  A
+   fatal error or no samples processed at all is BAD.  A command line
+   USAGE exit is generated by argp_error. */
 #define EXIT_OK     0
 #define EXIT_ERROR  1
 #define EXIT_BAD    2
@@ -152,11 +159,41 @@ Utility is a work-in-progress, see README.eu-stacktrace in the source branch.")
 
   argp_parse(&argp, argc, argv, 0, NULL, NULL);
 
-  /* hello world */
-#ifdef HAVE_SYSPROF_4_HEADERS
-  printf("hello sysprof: %x\n", SYSPROF_CAPTURE_MAGIC);
-#else
+#ifndef HAVE_SYSPROF_4_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."));
 #endif
+
+  /* TODO Also handle common expansions e.g. ~/foo instead of /home/user/foo. */
+  /* TODO Also handle '-' path for stdin/stdout. */
+  input_fd = open (input_path, O_RDONLY);
+  if (input_fd < 0)
+    error (EXIT_BAD, errno, N_("Cannot open input file or FIFO '%s'"), input_path);
+  output_fd = open (output_path, O_WRONLY);
+  if (output_fd < 0)
+    error (EXIT_BAD, errno, N_("Cannot open output file or FIFO '%s'"), output_path);
+
+  /* TODO For now, just pipe data through with no packet separation. Just a quick 'cat' hack. */
+  passthru_buffer_len = 8192;
+  passthru_buffer = (char *)malloc (passthru_buffer_len);
+  for (;;)
+    {
+      ssize_t n_read;
+      n_read = read (input_fd, passthru_buffer, passthru_buffer_len);
+      if (n_read < 0)
+       error (EXIT_BAD, errno, N_("Read error from file or FIFO '%s'"), input_path);
+      if (n_read == 0)
+       break;
+      if (n_read != write (output_fd, passthru_buffer, n_read))
+       error (EXIT_BAD, errno, N_("Write error to file or FIFO '%s'"), output_path);
+    }
+  free (passthru_buffer);
+  /* TODO Also support mode none, which outputs nothing. */
+
+  if (input_fd != -1)
+    close (input_fd);
+  if (output_fd != -1)
+    close (output_fd);
+
+  return EXIT_OK;
 }