[sysprof] libsysprof: use SYSPROF_TRACE_FD env var when spawning
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [sysprof] libsysprof: use SYSPROF_TRACE_FD env var when spawning
- Date: Wed, 29 May 2019 22:41:47 +0000 (UTC)
commit 3321308c4af7e0dca7213bcb9f31ffe66d1de176
Author: Christian Hergert <chergert redhat com>
Date: Tue May 21 21:58:24 2019 -0700
libsysprof: use SYSPROF_TRACE_FD env var when spawning
This avoids connecting to the bus which is racey, and instead just hands
the FD off to the subprocess.
src/libsysprof/sysprof-proxy-source.c | 70 ++++++++++++++++++++++++++++++-----
1 file changed, 60 insertions(+), 10 deletions(-)
---
diff --git a/src/libsysprof/sysprof-proxy-source.c b/src/libsysprof/sysprof-proxy-source.c
index 6d95744..f47a37d 100644
--- a/src/libsysprof/sysprof-proxy-source.c
+++ b/src/libsysprof/sysprof-proxy-source.c
@@ -149,7 +149,7 @@ sysprof_proxy_source_take_monitor (SysprofProxySource *self,
g_assert (SYSPROF_IS_PROXY_SOURCE (self));
g_assert (monitor != NULL);
g_assert (monitor->self == self);
- g_assert (G_IS_DBUS_CONNECTION (monitor->bus));
+ g_assert (monitor->bus == NULL || G_IS_DBUS_CONNECTION (monitor->bus));
if (g_cancellable_is_cancelled (self->cancellable))
monitor_free (monitor);
@@ -200,7 +200,7 @@ sysprof_proxy_source_monitor (SysprofProxySource *self,
gint handle;
g_assert (SYSPROF_IS_PROXY_SOURCE (self));
- g_assert (G_IS_DBUS_CONNECTION (self));
+ g_assert (G_IS_DBUS_CONNECTION (bus));
g_assert (bus_name != NULL);
if (g_cancellable_is_cancelled (self->cancellable))
@@ -397,13 +397,31 @@ sysprof_proxy_source_cat (SysprofProxySource *self,
}
}
+static void
+sysprof_proxy_source_complete_monitor (SysprofProxySource *self,
+ Monitor *monitor)
+{
+ g_autoptr(SysprofCaptureReader) reader = NULL;
+ g_autoptr(GError) error = NULL;
+
+ g_assert (SYSPROF_IS_PROXY_SOURCE (self));
+ g_assert (monitor != NULL);
+ g_assert (monitor->self == self);
+
+ g_print ("completing with FD: %d\n", monitor->fd);
+
+ if (!(reader = sysprof_capture_reader_new_from_fd (steal_fd (&monitor->fd), &error)))
+ g_warning ("Failed to load reader from peer FD: %s", error->message);
+ else
+ sysprof_proxy_source_cat (self, reader);
+}
+
static void
sysprof_proxy_source_stop_cb (GObject *object,
GAsyncResult *result,
gpointer user_data)
{
GDBusConnection *bus = (GDBusConnection *)object;
- g_autoptr(SysprofCaptureReader) reader = NULL;
g_autoptr(Monitor) monitor = user_data;
g_autoptr(GVariant) reply = NULL;
g_autoptr(GError) error = NULL;
@@ -417,12 +435,7 @@ sysprof_proxy_source_stop_cb (GObject *object,
reply = g_dbus_connection_call_finish (bus, result, &error);
monitor->needs_stop = FALSE;
- /* TODO: Read back memfd containing data from peer */
-
- if (!(reader = sysprof_capture_reader_new_from_fd (steal_fd (&monitor->fd), &error)))
- g_warning ("Failed to load reader from peer FD: %s", error->message);
- else
- sysprof_proxy_source_cat (self, reader);
+ sysprof_proxy_source_complete_monitor (self, monitor);
self->stopping_count--;
@@ -463,7 +476,7 @@ sysprof_proxy_source_stop (SysprofSource *source)
}
else
{
- /* Do nothing, as we never got the data setup */
+ sysprof_proxy_source_complete_monitor (self, monitor);
}
}
@@ -486,6 +499,39 @@ sysprof_proxy_source_add_pid (SysprofSource *source,
g_array_append_val (self->pids, pid);
}
+static void
+sysprof_proxy_source_modify_spawn (SysprofSource *source,
+ GSubprocessLauncher *launcher,
+ GPtrArray *argv)
+{
+ SysprofProxySource *self = (SysprofProxySource *)source;
+ gchar fdstr[12];
+ Monitor *monitor;
+ gint fd;
+
+ g_assert (SYSPROF_IS_PROXY_SOURCE (self));
+ g_assert (G_IS_SUBPROCESS_LAUNCHER (launcher));
+ g_assert (argv != NULL);
+
+ /* We need to create a new FD for the peer process to write
+ * to and notify it via SYSPROF_TRACE_FD. We will largely
+ * ignore things until the capture has finished.
+ */
+
+ if (-1 == (fd = sysprof_memfd_create ("[sysprof-proxy-capture]")))
+ return;
+
+ monitor = g_slice_new0 (Monitor);
+ monitor->self = g_object_ref (self);
+ monitor->fd = dup (fd);
+
+ g_snprintf (fdstr, sizeof fdstr, "%d", fd);
+ g_subprocess_launcher_setenv (launcher, "SYSPROF_TRACE_FD", fdstr, TRUE);
+ g_subprocess_launcher_take_fd (launcher, fd, fd);
+
+ sysprof_proxy_source_take_monitor (self, g_steal_pointer (&monitor));
+}
+
static void
source_iface_init (SysprofSourceInterface *iface)
{
@@ -495,6 +541,7 @@ source_iface_init (SysprofSourceInterface *iface)
iface->get_is_ready = sysprof_proxy_source_get_is_ready;
iface->stop = sysprof_proxy_source_stop;
iface->start = sysprof_proxy_source_start;
+ iface->modify_spawn = sysprof_proxy_source_modify_spawn;
}
G_DEFINE_TYPE_WITH_CODE (SysprofProxySource, sysprof_proxy_source, G_TYPE_OBJECT,
@@ -543,6 +590,9 @@ sysprof_proxy_source_new (GBusType bus_type,
g_return_val_if_fail (bus_name != NULL, NULL);
g_return_val_if_fail (object_path != NULL, NULL);
+ if (bus_name && !*bus_name)
+ bus_name = NULL;
+
self = g_object_new (SYSPROF_TYPE_PROXY_SOURCE, NULL);
self->bus_type = bus_type;
self->bus_name = g_strdup (bus_name);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]