From 974cbf5130625b80460c67407ca7341e2802ccf5 Mon Sep 17 00:00:00 2001 From: Christian Hergert Date: Thu, 23 May 2019 17:20:29 -0700 Subject: [PATCH] libsysprof: add helper to create profiler from capture reader This will look at what was in the reader before and create a new local profiler from that. This still needs to add support for restoring info from sources which need to be inflated. --- src/libsysprof/sysprof-local-profiler.c | 74 ++++++++++++++++++++++++- src/libsysprof/sysprof-local-profiler.h | 4 +- 2 files changed, 75 insertions(+), 3 deletions(-) diff --git a/src/libsysprof/sysprof-local-profiler.c b/src/libsysprof/sysprof-local-profiler.c index bbd1fa30..03ab0281 100644 --- a/src/libsysprof/sysprof-local-profiler.c +++ b/src/libsysprof/sysprof-local-profiler.c @@ -18,18 +18,23 @@ * SPDX-License-Identifier: GPL-3.0-or-later */ +#define G_LOG_DOMAIN "sysprof-local-profiler" + #include "config.h" +#include +#include #include #include -#include -#include +#include #include #include "sysprof-helpers.h" #include "sysprof-local-profiler.h" #include "sysprof-platform.h" +#define CSTRV(s) ((const gchar * const *)s) + typedef struct { SysprofCaptureWriter *writer; @@ -935,3 +940,68 @@ profiler_iface_init (SysprofProfilerInterface *iface) iface->stop = sysprof_local_profiler_stop; iface->stopped = sysprof_local_profiler_real_stopped; } + +static gboolean +find_profiler_meta_cb (const SysprofCaptureFrame *frame, + gpointer user_data) +{ + const SysprofCaptureMetadata *meta = (const SysprofCaptureMetadata *)frame; + GKeyFile **keyfile = user_data; + + g_assert (frame != NULL); + g_assert (frame->type == SYSPROF_CAPTURE_FRAME_METADATA); + g_assert (keyfile != NULL); + g_assert (*keyfile == NULL); + + if (g_strcmp0 (meta->id, "local-profiler") == 0) + { + g_autoptr(GKeyFile) kf = g_key_file_new (); + + /* Metadata is guaranteed to be \0 terminated by marshaller */ + if (g_key_file_load_from_data (kf, meta->metadata, -1, 0, NULL)) + *keyfile = g_steal_pointer (&kf); + + return *keyfile == NULL; + } + + return TRUE; +} + +SysprofProfiler * +sysprof_local_profiler_new_replay (SysprofCaptureReader *reader) +{ + static const SysprofCaptureFrameType mtype[] = { + SYSPROF_CAPTURE_FRAME_METADATA, + }; + g_autoptr(SysprofLocalProfiler) self = NULL; + g_autoptr(SysprofCaptureCursor) cursor = NULL; + g_autoptr(GKeyFile) keyfile = NULL; + g_auto(GStrv) argv = NULL; + g_auto(GStrv) env = NULL; + gboolean inherit; + gboolean spawn; + + g_return_val_if_fail (reader != NULL, NULL); + + self = g_object_new (SYSPROF_TYPE_LOCAL_PROFILER, NULL); + + cursor = sysprof_capture_cursor_new (reader); + sysprof_capture_cursor_add_condition (cursor, sysprof_capture_condition_new_where_type_in (1, mtype)); + sysprof_capture_cursor_foreach (cursor, find_profiler_meta_cb, &keyfile); + + /* No metadata, bail */ + if (keyfile == NULL) + return NULL; + + spawn = g_key_file_get_boolean (keyfile, "profiler", "spawn", NULL); + inherit = g_key_file_get_boolean (keyfile, "profiler", "spawn-inherit-environ", NULL); + argv = g_key_file_get_string_list (keyfile, "profiler", "spawn-argv", NULL, NULL); + env = g_key_file_get_string_list (keyfile, "profiler", "spawn-env", NULL, NULL); + + sysprof_profiler_set_spawn (SYSPROF_PROFILER (self), spawn); + sysprof_profiler_set_spawn_argv (SYSPROF_PROFILER (self), CSTRV (argv)); + sysprof_profiler_set_spawn_env (SYSPROF_PROFILER (self), CSTRV (env)); + sysprof_profiler_set_spawn_inherit_environ (SYSPROF_PROFILER (self), inherit); + + return SYSPROF_PROFILER (g_steal_pointer (&self)); +} diff --git a/src/libsysprof/sysprof-local-profiler.h b/src/libsysprof/sysprof-local-profiler.h index 3cf61328..62e7a69c 100644 --- a/src/libsysprof/sysprof-local-profiler.h +++ b/src/libsysprof/sysprof-local-profiler.h @@ -41,6 +41,8 @@ struct _SysprofLocalProfilerClass }; SYSPROF_AVAILABLE_IN_ALL -SysprofProfiler *sysprof_local_profiler_new (void); +SysprofProfiler *sysprof_local_profiler_new (void); +SYSPROF_AVAILABLE_IN_ALL +SysprofProfiler *sysprof_local_profiler_new_replay (SysprofCaptureReader *reader); G_END_DECLS