diff --git a/examples/app.c b/examples/app.c new file mode 100644 index 00000000..e3bfb1e1 --- /dev/null +++ b/examples/app.c @@ -0,0 +1,79 @@ +/* This code is public domain */ + +/* The following is an example of how to use the SYSPROF_TRACE_FD + * environment set by Sysprof to add marks or other information + * to the capture from your application. + */ + +#define _GNU_SOURCE + +#include +#include +#include +#include + +static void do_some_work (SysprofCaptureWriter *); + +int +main (int argc, + char *argv[]) +{ + SysprofCaptureWriter *writer; + + /* Ignore SIGPIPE because we might get a pipe from the environment and we + * don't want to trap if write() is used on it. + */ + signal (SIGPIPE, SIG_IGN); + + /* This will check for SYSPROF_TRACE_FD=N, parse the FD number, and use it as + * the backing file for the trace data. It may be a file, socket, pipe, + * memfd, etc. To reduce chances of the FD being used a second time, this + * function will also set the environment variable to "" by overwriting the + * first byte to \0. + */ + writer = sysprof_capture_writer_new_from_env (0); + + /* Nothing to do */ + if (writer == NULL) + { + g_printerr ("SYSPROF_TRACE_FD not found, exiting.\n"); + return 1; + } + + do_some_work (writer); + + sysprof_capture_writer_unref (writer); + + return 0; +} + +static void +do_some_work (SysprofCaptureWriter *writer) +{ + const gint64 duration_usec = G_USEC_PER_SEC / 60L; + + /* Wait a few seconds to get started */ + g_usleep (G_USEC_PER_SEC * 3); + + for (guint i = 0; i < 120; i++) + { + gint64 begin_time_nsec = SYSPROF_CAPTURE_CURRENT_TIME; + gint64 real_duration; + gint64 end_time_nsec; + + g_usleep (duration_usec); + + end_time_nsec = SYSPROF_CAPTURE_CURRENT_TIME; + real_duration = end_time_nsec - begin_time_nsec; + + sysprof_capture_writer_add_mark (writer, + begin_time_nsec, /* Begin time in nsec */ + sched_getcpu (), /* -1 to ignore */ + getpid (), /* -1 to ignore */ + real_duration, /* duration in nsec */ + "Example", /* Group name, 23 chars+\0 */ + "Sleep", /* Name, 39 chars+\0 */ + "Anscillary message data"); /* UTF-8 Message data, limited to + 64kb-frame size. */ + } +} diff --git a/examples/meson.build b/examples/meson.build new file mode 100644 index 00000000..124ac241 --- /dev/null +++ b/examples/meson.build @@ -0,0 +1,3 @@ +app = executable('example-app', 'app.c', + dependencies: [libsysprof_capture_dep], +) diff --git a/meson.build b/meson.build index 4c8b8571..b61911c9 100644 --- a/meson.build +++ b/meson.build @@ -174,6 +174,7 @@ configure_file( subdir('src') subdir('data') +subdir('examples') subdir('help') subdir('po') diff --git a/src/libsysprof-capture/sysprof-capture-writer.c b/src/libsysprof-capture/sysprof-capture-writer.c index 0440d784..d7ef09d1 100644 --- a/src/libsysprof-capture/sysprof-capture-writer.c +++ b/src/libsysprof-capture/sysprof-capture-writer.c @@ -426,8 +426,8 @@ sysprof_capture_writer_new_from_fd (int fd, g_assert (fd != -1); g_assert (buffer_size % _sysprof_getpagesize() == 0); - if (ftruncate (fd, 0) != 0) - return NULL; + /* This is only useful on files, memfd, etc */ + ftruncate (fd, 0); self = g_new0 (SysprofCaptureWriter, 1); self->ref_count = 1; @@ -1287,6 +1287,9 @@ sysprof_capture_writer_new_from_env (gsize buffer_size) if (!(fdstr = g_getenv ("SYSPROF_TRACE_FD"))) return NULL; + /* Make sure the clock is initialized */ + sysprof_clock_init (); + if (!(fd = atoi (fdstr))) return NULL;