sysprof/0015-libsysprof-add-support-for-stack-regs-options-in-att.patch

139 lines
6.6 KiB
Diff
Raw Normal View History

2024-11-27 17:36:40 +00:00
From 5fbfc3b1ce324868fa48c00f12ceea0a07e4dcda Mon Sep 17 00:00:00 2001
From: Christian Hergert <chergert@redhat.com>
Date: Sun, 3 Nov 2024 10:39:23 -0800
2024-11-27 17:36:40 +00:00
Subject: [PATCH 15/33] libsysprof: add support for stack/regs options in attr
This requires a coordinating sysprofd that knows how to handle reading the
new attributes. Setting these fields will allow snapshotting the contents
of the stack and registers to do offline unwinding.
Also make the conversion to GVariant available outside the module so that
we can consume it for live unwinding.
---
.../sysprof-perf-event-stream-private.h | 25 ++++++++++---------
src/libsysprof/sysprof-perf-event-stream.c | 10 +++++---
src/sysprofd/helpers.c | 16 ++++++++++++
3 files changed, 36 insertions(+), 15 deletions(-)
diff --git a/src/libsysprof/sysprof-perf-event-stream-private.h b/src/libsysprof/sysprof-perf-event-stream-private.h
index 4ac0fd1e..7e3d9deb 100644
--- a/src/libsysprof/sysprof-perf-event-stream-private.h
+++ b/src/libsysprof/sysprof-perf-event-stream-private.h
@@ -165,17 +165,18 @@ typedef void (*SysprofPerfEventCallback) (const SysprofPerfEvent *event,
G_DECLARE_FINAL_TYPE (SysprofPerfEventStream, sysprof_perf_event_stream, SYSPROF, PERF_EVENT_STREAM, GObject)
-DexFuture *sysprof_perf_event_stream_new (GDBusConnection *connection,
- struct perf_event_attr *attr,
- int cpu,
- int group_fd,
- guint64 flags,
- SysprofPerfEventCallback callback,
- gpointer callback_data,
- GDestroyNotify callback_data_destroy);
-gboolean sysprof_perf_event_stream_enable (SysprofPerfEventStream *self,
- GError **error);
-gboolean sysprof_perf_event_stream_disable (SysprofPerfEventStream *self,
- GError **error);
+DexFuture *sysprof_perf_event_stream_new (GDBusConnection *connection,
+ struct perf_event_attr *attr,
+ int cpu,
+ int group_fd,
+ guint64 flags,
+ SysprofPerfEventCallback callback,
+ gpointer callback_data,
+ GDestroyNotify callback_data_destroy);
+gboolean sysprof_perf_event_stream_enable (SysprofPerfEventStream *self,
+ GError **error);
+gboolean sysprof_perf_event_stream_disable (SysprofPerfEventStream *self,
+ GError **error);
+GVariant *_sysprof_perf_event_attr_to_variant (const struct perf_event_attr *attr);
G_END_DECLS
diff --git a/src/libsysprof/sysprof-perf-event-stream.c b/src/libsysprof/sysprof-perf-event-stream.c
index a7bf8d88..c40182ad 100644
--- a/src/libsysprof/sysprof-perf-event-stream.c
+++ b/src/libsysprof/sysprof-perf-event-stream.c
@@ -109,8 +109,8 @@ G_DEFINE_FINAL_TYPE (SysprofPerfEventStream, sysprof_perf_event_stream, G_TYPE_O
static GParamSpec *properties [N_PROPS];
-static GVariant *
-build_options_dict (const struct perf_event_attr *attr)
+GVariant *
+_sysprof_perf_event_attr_to_variant (const struct perf_event_attr *attr)
{
return g_variant_take_ref (
g_variant_new_parsed ("["
@@ -130,6 +130,8 @@ build_options_dict (const struct perf_event_attr *attr)
"{'sample_period', <%t>},"
"{'sample_type', <%t>},"
"{'task', <%b>},"
+ "{'sample_stack_user', <%u>},"
+ "{'sample_regs_user', <%t>},"
"{'type', <%u>}"
"]",
(gboolean)!!attr->comm,
@@ -148,6 +150,8 @@ build_options_dict (const struct perf_event_attr *attr)
(guint64)attr->sample_period,
(guint64)attr->sample_type,
(gboolean)!!attr->task,
+ (guint32)attr->sample_stack_user,
+ (guint64)attr->sample_regs_user,
(guint32)attr->type));
}
@@ -513,7 +517,7 @@ sysprof_perf_event_stream_new (GDBusConnection *connection,
group_fd_handle = g_unix_fd_list_append (fd_list, group_fd, NULL);
}
- options = build_options_dict (attr);
+ options = _sysprof_perf_event_attr_to_variant (attr);
g_dbus_connection_call_with_unix_fd_list (connection,
"org.gnome.Sysprof3",
diff --git a/src/sysprofd/helpers.c b/src/sysprofd/helpers.c
index 2aebc417..7e5df34a 100644
--- a/src/sysprofd/helpers.c
+++ b/src/sysprofd/helpers.c
@@ -127,6 +127,8 @@ helpers_perf_event_open (GVariant *options,
guint64 sample_period = 0;
guint64 sample_type = 0;
guint64 config = 0;
+ guint64 sample_regs_user = 0;
+ guint sample_stack_user = 0;
int clockid = CLOCK_MONOTONIC;
int comm = 0;
int mmap_ = 0;
@@ -236,6 +238,18 @@ helpers_perf_event_open (GVariant *options,
goto bad_arg;
use_clockid = g_variant_get_boolean (value);
}
+ else if (strcmp (key, "sample_stack_user") == 0)
+ {
+ if (!g_variant_is_of_type (value, G_VARIANT_TYPE_UINT32))
+ goto bad_arg;
+ sample_stack_user = g_variant_get_uint32 (value);
+ }
+ else if (strcmp (key, "sample_regs_user") == 0)
+ {
+ if (!g_variant_is_of_type (value, G_VARIANT_TYPE_UINT64))
+ goto bad_arg;
+ sample_regs_user = g_variant_get_uint64 (value);
+ }
continue;
@@ -257,6 +271,8 @@ helpers_perf_event_open (GVariant *options,
attr.task = !!task;
attr.type = type;
attr.wakeup_events = wakeup_events;
+ attr.sample_regs_user = sample_regs_user;
+ attr.sample_stack_user = sample_stack_user;
#ifdef HAVE_PERF_CLOCKID
if (!use_clockid || clockid < 0)
--
2.45.2