mirror of
https://github.com/varun-r-mallya/sysprof.git
synced 2026-02-11 07:30:54 +00:00
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.
This commit is contained in:
@ -149,7 +149,7 @@ sysprof_proxy_source_take_monitor (SysprofProxySource *self,
|
|||||||
g_assert (SYSPROF_IS_PROXY_SOURCE (self));
|
g_assert (SYSPROF_IS_PROXY_SOURCE (self));
|
||||||
g_assert (monitor != NULL);
|
g_assert (monitor != NULL);
|
||||||
g_assert (monitor->self == self);
|
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))
|
if (g_cancellable_is_cancelled (self->cancellable))
|
||||||
monitor_free (monitor);
|
monitor_free (monitor);
|
||||||
@ -200,7 +200,7 @@ sysprof_proxy_source_monitor (SysprofProxySource *self,
|
|||||||
gint handle;
|
gint handle;
|
||||||
|
|
||||||
g_assert (SYSPROF_IS_PROXY_SOURCE (self));
|
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);
|
g_assert (bus_name != NULL);
|
||||||
|
|
||||||
if (g_cancellable_is_cancelled (self->cancellable))
|
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
|
static void
|
||||||
sysprof_proxy_source_stop_cb (GObject *object,
|
sysprof_proxy_source_stop_cb (GObject *object,
|
||||||
GAsyncResult *result,
|
GAsyncResult *result,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
GDBusConnection *bus = (GDBusConnection *)object;
|
GDBusConnection *bus = (GDBusConnection *)object;
|
||||||
g_autoptr(SysprofCaptureReader) reader = NULL;
|
|
||||||
g_autoptr(Monitor) monitor = user_data;
|
g_autoptr(Monitor) monitor = user_data;
|
||||||
g_autoptr(GVariant) reply = NULL;
|
g_autoptr(GVariant) reply = NULL;
|
||||||
g_autoptr(GError) error = 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);
|
reply = g_dbus_connection_call_finish (bus, result, &error);
|
||||||
monitor->needs_stop = FALSE;
|
monitor->needs_stop = FALSE;
|
||||||
|
|
||||||
/* TODO: Read back memfd containing data from peer */
|
sysprof_proxy_source_complete_monitor (self, monitor);
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
self->stopping_count--;
|
self->stopping_count--;
|
||||||
|
|
||||||
@ -463,7 +476,7 @@ sysprof_proxy_source_stop (SysprofSource *source)
|
|||||||
}
|
}
|
||||||
else
|
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);
|
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
|
static void
|
||||||
source_iface_init (SysprofSourceInterface *iface)
|
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->get_is_ready = sysprof_proxy_source_get_is_ready;
|
||||||
iface->stop = sysprof_proxy_source_stop;
|
iface->stop = sysprof_proxy_source_stop;
|
||||||
iface->start = sysprof_proxy_source_start;
|
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,
|
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 (bus_name != NULL, NULL);
|
||||||
g_return_val_if_fail (object_path != 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 = g_object_new (SYSPROF_TYPE_PROXY_SOURCE, NULL);
|
||||||
self->bus_type = bus_type;
|
self->bus_type = bus_type;
|
||||||
self->bus_name = g_strdup (bus_name);
|
self->bus_name = g_strdup (bus_name);
|
||||||
|
|||||||
Reference in New Issue
Block a user