libsysprof: do process setup before recording starts

Otherwise we end up recording ourselves too much. Do it before even though
there is a small race condition chance to miss a process spawning at the
time between prepare and record.
This commit is contained in:
Christian Hergert
2023-08-04 12:17:16 -07:00
parent b2ce9efbb4
commit a286c2a8cb

View File

@ -302,7 +302,11 @@ static DexFuture *
sysprof_linux_instrument_prepare_fiber (gpointer user_data)
{
SysprofRecording *recording = user_data;
g_autoptr(GDBusConnection) bus = NULL;
g_autoptr(GVariant) process_info_reply = NULL;
g_autoptr(GVariant) process_info = NULL;
g_autoptr(GError) error = NULL;
gint64 at_time;
g_assert (SYSPROF_IS_RECORDING (recording));
@ -320,40 +324,14 @@ sysprof_linux_instrument_prepare_fiber (gpointer user_data)
add_process_output_as_file (recording, "glxinfo", "glxinfo", TRUE);
add_process_output_as_file (recording, "lsusb -v", "lsusb", TRUE);
return dex_future_new_for_boolean (TRUE);
}
static DexFuture *
sysprof_linux_instrument_prepare (SysprofInstrument *instrument,
SysprofRecording *recording)
{
g_assert (SYSPROF_IS_INSTRUMENT (instrument));
g_assert (SYSPROF_IS_RECORDING (recording));
return dex_scheduler_spawn (NULL, 0,
sysprof_linux_instrument_prepare_fiber,
g_object_ref (recording),
g_object_unref);
}
static DexFuture *
sysprof_linux_instrument_record_fiber (gpointer user_data)
{
SysprofRecording *recording = user_data;
g_autoptr(GDBusConnection) bus = NULL;
g_autoptr(GVariant) process_info_reply = NULL;
g_autoptr(GVariant) process_info = NULL;
g_autoptr(GError) error = NULL;
gint64 at_time;
g_assert (SYSPROF_IS_RECORDING (recording));
/* We need access to the bus to call various sysprofd API directly */
if (!(bus = dex_await_object (dex_bus_get (G_BUS_TYPE_SYSTEM), &error)))
return dex_future_new_for_error (g_steal_pointer (&error));
/* We also want to get a bunch of info on user processes so that we can add
* records about them to the recording.
/* Normally we would want to do this once recording has started since we
* want to reduce the chances we miss a process being executed. But that
* race condition exists anyway so instead do it during prepare so that
* we don't waste so much time on our profiles with our own process.
*/
at_time = SYSPROF_CAPTURE_CURRENT_TIME;
if (!(process_info_reply = dex_await_variant (dex_dbus_connection_call (bus,
@ -376,15 +354,14 @@ sysprof_linux_instrument_record_fiber (gpointer user_data)
}
static DexFuture *
sysprof_linux_instrument_record (SysprofInstrument *instrument,
SysprofRecording *recording,
GCancellable *cancellable)
sysprof_linux_instrument_prepare (SysprofInstrument *instrument,
SysprofRecording *recording)
{
g_assert (SYSPROF_IS_INSTRUMENT (instrument));
g_assert (SYSPROF_IS_RECORDING (recording));
return dex_scheduler_spawn (NULL, 0,
sysprof_linux_instrument_record_fiber,
sysprof_linux_instrument_prepare_fiber,
g_object_ref (recording),
g_object_unref);
}
@ -424,7 +401,6 @@ sysprof_linux_instrument_class_init (SysprofLinuxInstrumentClass *klass)
instrument_class->list_required_policy = sysprof_linux_instrument_list_required_policy;
instrument_class->prepare = sysprof_linux_instrument_prepare;
instrument_class->record = sysprof_linux_instrument_record;
instrument_class->process_started = sysprof_linux_instrument_process_started;
}