2024-11-27 17:36:40 +00:00
|
|
|
From 5fbfc3b1ce324868fa48c00f12ceea0a07e4dcda Mon Sep 17 00:00:00 2001
|
2024-11-06 20:39:21 +00:00
|
|
|
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
|
2024-11-06 20:39:21 +00:00
|
|
|
|
|
|
|
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
|
|
|
|
|