Compare commits
No commits in common. "c9-beta" and "c10s" have entirely different histories.
3
.gitignore
vendored
3
.gitignore
vendored
@ -1 +1,2 @@
|
||||
SOURCES/sysprof-3.40.1.tar.xz
|
||||
/sysprof-*.tar.xz
|
||||
/libunwind-1.8.1.tar.gz
|
||||
|
@ -1 +0,0 @@
|
||||
a2c1e951c4332a4efb0c702025d896ca175bb6fa SOURCES/sysprof-3.40.1.tar.xz
|
42
0001-build-add-47-version-macros.patch
Normal file
42
0001-build-add-47-version-macros.patch
Normal file
@ -0,0 +1,42 @@
|
||||
From 86cd5222dc05e81305ffb22a49cb453c2f90e055 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Hergert <chergert@redhat.com>
|
||||
Date: Wed, 13 Nov 2024 16:11:47 -0800
|
||||
Subject: [PATCH 01/31] build: add 47 version macros
|
||||
|
||||
---
|
||||
src/libsysprof-capture/sysprof-version-macros.h | 15 +++++++++++++++
|
||||
1 file changed, 15 insertions(+)
|
||||
|
||||
diff --git a/src/libsysprof-capture/sysprof-version-macros.h b/src/libsysprof-capture/sysprof-version-macros.h
|
||||
index 67dac287..d11b6bc9 100644
|
||||
--- a/src/libsysprof-capture/sysprof-version-macros.h
|
||||
+++ b/src/libsysprof-capture/sysprof-version-macros.h
|
||||
@@ -91,6 +91,7 @@
|
||||
#define SYSPROF_VERSION_3_38 (SYSPROF_ENCODE_VERSION (3, 38, 0))
|
||||
#define SYSPROF_VERSION_3_40 (SYSPROF_ENCODE_VERSION (3, 40, 0))
|
||||
#define SYSPROF_VERSION_3_46 (SYSPROF_ENCODE_VERSION (3, 46, 0))
|
||||
+#define SYSPROF_VERSION_47 (SYSPROF_ENCODE_VERSION (47, 0, 0))
|
||||
|
||||
#if (SYSPROF_MINOR_VERSION == 99)
|
||||
# define SYSPROF_VERSION_CUR_STABLE (SYSPROF_ENCODE_VERSION (SYSPROF_MAJOR_VERSION + 1, 0, 0))
|
||||
@@ -232,3 +233,17 @@
|
||||
#else
|
||||
# define SYSPROF_AVAILABLE_IN_3_46 _SYSPROF_EXTERN
|
||||
#endif
|
||||
+
|
||||
+#if SYSPROF_VERSION_MIN_REQUIRED >= SYSPROF_VERSION_47
|
||||
+# define SYSPROF_DEPRECATED_IN_47 SYSPROF_DEPRECATED
|
||||
+# define SYSPROF_DEPRECATED_IN_47_FOR(f) SYSPROF_DEPRECATED_FOR(f)
|
||||
+#else
|
||||
+# define SYSPROF_DEPRECATED_IN_47 _SYSPROF_EXTERN
|
||||
+# define SYSPROF_DEPRECATED_IN_47_FOR(f) _SYSPROF_EXTERN
|
||||
+#endif
|
||||
+
|
||||
+#if SYSPROF_VERSION_MAX_ALLOWED < SYSPROF_VERSION_47
|
||||
+# define SYSPROF_AVAILABLE_IN_47 SYSPROF_UNAVAILABLE(47, 0)
|
||||
+#else
|
||||
+# define SYSPROF_AVAILABLE_IN_47 _SYSPROF_EXTERN
|
||||
+#endif
|
||||
--
|
||||
2.45.2
|
||||
|
@ -0,0 +1,28 @@
|
||||
From c7910ee7b9f8d2b15f0b05f33e2280e3861ba9fe Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Barnab=C3=A1s=20P=C5=91cze?= <pobrn@protonmail.com>
|
||||
Date: Wed, 9 Oct 2024 15:29:59 +0200
|
||||
Subject: [PATCH 02/31] libsysprof: elf: do not allow setting self as debug
|
||||
link
|
||||
|
||||
That will cause infinite recursion in `sysprof_elf_get_symbol_at_address_internal()`.
|
||||
Also note that loops are still possible, this change
|
||||
only prevents one way of creating loops.
|
||||
---
|
||||
src/libsysprof/sysprof-elf.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/src/libsysprof/sysprof-elf.c b/src/libsysprof/sysprof-elf.c
|
||||
index f4e5f914..0534eccb 100644
|
||||
--- a/src/libsysprof/sysprof-elf.c
|
||||
+++ b/src/libsysprof/sysprof-elf.c
|
||||
@@ -502,6 +502,7 @@ sysprof_elf_set_debug_link_elf (SysprofElf *self,
|
||||
{
|
||||
g_return_if_fail (SYSPROF_IS_ELF (self));
|
||||
g_return_if_fail (!debug_link_elf || SYSPROF_IS_ELF (debug_link_elf));
|
||||
+ g_return_if_fail (debug_link_elf != self);
|
||||
|
||||
if (g_set_object (&self->debug_link_elf, debug_link_elf))
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_DEBUG_LINK_ELF]);
|
||||
--
|
||||
2.45.2
|
||||
|
140
0003-libsysprof-elf-do-not-generate-fallback-names.patch
Normal file
140
0003-libsysprof-elf-do-not-generate-fallback-names.patch
Normal file
@ -0,0 +1,140 @@
|
||||
From 8a8b5b25ff8cb9119fc781ea686826723c93d2ff Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Barnab=C3=A1s=20P=C5=91cze?= <pobrn@protonmail.com>
|
||||
Date: Wed, 9 Oct 2024 15:28:14 +0200
|
||||
Subject: [PATCH 03/31] libsysprof: elf: do not generate fallback names
|
||||
|
||||
Fallback names are only used in `SysprofElfSymbolizer` at the
|
||||
moment, but it also has code to generate fallback symbols.
|
||||
---
|
||||
src/libsysprof/sysprof-elf-private.h | 3 +--
|
||||
src/libsysprof/sysprof-elf-symbolizer.c | 12 ++++++------
|
||||
src/libsysprof/sysprof-elf.c | 17 +++++------------
|
||||
3 files changed, 12 insertions(+), 20 deletions(-)
|
||||
|
||||
diff --git a/src/libsysprof/sysprof-elf-private.h b/src/libsysprof/sysprof-elf-private.h
|
||||
index b4d0f737..146bc2de 100644
|
||||
--- a/src/libsysprof/sysprof-elf-private.h
|
||||
+++ b/src/libsysprof/sysprof-elf-private.h
|
||||
@@ -42,8 +42,7 @@ const char *sysprof_elf_get_debug_link (SysprofElf *self);
|
||||
char *sysprof_elf_get_symbol_at_address (SysprofElf *self,
|
||||
guint64 address,
|
||||
guint64 *begin_address,
|
||||
- guint64 *end_address,
|
||||
- gboolean *is_fallback);
|
||||
+ guint64 *end_address);
|
||||
SysprofElf *sysprof_elf_get_debug_link_elf (SysprofElf *self);
|
||||
void sysprof_elf_set_debug_link_elf (SysprofElf *self,
|
||||
SysprofElf *debug_link_elf);
|
||||
diff --git a/src/libsysprof/sysprof-elf-symbolizer.c b/src/libsysprof/sysprof-elf-symbolizer.c
|
||||
index 8fdf204f..f7aabef7 100644
|
||||
--- a/src/libsysprof/sysprof-elf-symbolizer.c
|
||||
+++ b/src/libsysprof/sysprof-elf-symbolizer.c
|
||||
@@ -61,9 +61,9 @@ sysprof_elf_symbolizer_symbolize (SysprofSymbolizer *symbolizer,
|
||||
g_autoptr(SysprofElf) elf = NULL;
|
||||
SysprofDocumentMmap *map;
|
||||
g_autofree char *name = NULL;
|
||||
+ const char *nick = NULL;
|
||||
const char *path;
|
||||
const char *build_id;
|
||||
- gboolean is_fallback = FALSE;
|
||||
guint64 map_begin;
|
||||
guint64 map_end;
|
||||
guint64 relative_address;
|
||||
@@ -115,14 +115,15 @@ sysprof_elf_symbolizer_symbolize (SysprofSymbolizer *symbolizer,
|
||||
NULL)))
|
||||
goto fallback;
|
||||
|
||||
+ nick = sysprof_elf_get_nick (elf);
|
||||
+
|
||||
/* Try to get the symbol name at the address and the begin/end address
|
||||
* so that it can be inserted into our symbol cache.
|
||||
*/
|
||||
if (!(name = sysprof_elf_get_symbol_at_address (elf,
|
||||
relative_address,
|
||||
&begin_address,
|
||||
- &end_address,
|
||||
- &is_fallback)))
|
||||
+ &end_address)))
|
||||
goto fallback;
|
||||
|
||||
/* Sanitize address ranges if we have to. Sometimes that can happen
|
||||
@@ -135,11 +136,10 @@ sysprof_elf_symbolizer_symbolize (SysprofSymbolizer *symbolizer,
|
||||
|
||||
ret = _sysprof_symbol_new (sysprof_strings_get (strings, name),
|
||||
sysprof_strings_get (strings, path),
|
||||
- sysprof_strings_get (strings, sysprof_elf_get_nick (elf)),
|
||||
+ sysprof_strings_get (strings, nick),
|
||||
map_begin + (begin_address - file_offset),
|
||||
map_begin + (end_address - file_offset),
|
||||
SYSPROF_SYMBOL_KIND_USER);
|
||||
- ret->is_fallback = is_fallback;
|
||||
|
||||
return ret;
|
||||
|
||||
@@ -156,7 +156,7 @@ fallback:
|
||||
|
||||
ret = _sysprof_symbol_new (sysprof_strings_get (strings, name),
|
||||
sysprof_strings_get (strings, path),
|
||||
- NULL,
|
||||
+ sysprof_strings_get (strings, nick),
|
||||
begin_address, end_address,
|
||||
SYSPROF_SYMBOL_KIND_USER);
|
||||
ret->is_fallback = TRUE;
|
||||
diff --git a/src/libsysprof/sysprof-elf.c b/src/libsysprof/sysprof-elf.c
|
||||
index 0534eccb..df73ce6d 100644
|
||||
--- a/src/libsysprof/sysprof-elf.c
|
||||
+++ b/src/libsysprof/sysprof-elf.c
|
||||
@@ -409,8 +409,7 @@ sysprof_elf_get_symbol_at_address_internal (SysprofElf *self,
|
||||
guint64 address,
|
||||
guint64 *begin_address,
|
||||
guint64 *end_address,
|
||||
- guint64 text_offset,
|
||||
- gboolean *is_fallback)
|
||||
+ guint64 text_offset)
|
||||
{
|
||||
const ElfSym *symbol;
|
||||
char *ret = NULL;
|
||||
@@ -421,7 +420,7 @@ sysprof_elf_get_symbol_at_address_internal (SysprofElf *self,
|
||||
|
||||
if (self->debug_link_elf != NULL)
|
||||
{
|
||||
- ret = sysprof_elf_get_symbol_at_address_internal (self->debug_link_elf, filename, address, begin_address, end_address, text_offset, is_fallback);
|
||||
+ ret = sysprof_elf_get_symbol_at_address_internal (self->debug_link_elf, filename, address, begin_address, end_address, text_offset);
|
||||
|
||||
if (ret != NULL)
|
||||
return ret;
|
||||
@@ -447,11 +446,7 @@ sysprof_elf_get_symbol_at_address_internal (SysprofElf *self,
|
||||
}
|
||||
else
|
||||
{
|
||||
- begin = address;
|
||||
- end = address + 1;
|
||||
- ret = g_strdup_printf ("In File %s+0x%"G_GINT64_MODIFIER"x", filename, address);
|
||||
- if (is_fallback)
|
||||
- *is_fallback = TRUE;
|
||||
+ return NULL;
|
||||
}
|
||||
|
||||
if (begin_address)
|
||||
@@ -467,16 +462,14 @@ char *
|
||||
sysprof_elf_get_symbol_at_address (SysprofElf *self,
|
||||
guint64 address,
|
||||
guint64 *begin_address,
|
||||
- guint64 *end_address,
|
||||
- gboolean *is_fallback)
|
||||
+ guint64 *end_address)
|
||||
{
|
||||
return sysprof_elf_get_symbol_at_address_internal (self,
|
||||
self->file,
|
||||
address,
|
||||
begin_address,
|
||||
end_address,
|
||||
- self->text_offset,
|
||||
- is_fallback);
|
||||
+ self->text_offset);
|
||||
}
|
||||
|
||||
/**
|
||||
--
|
||||
2.45.2
|
||||
|
53
0004-sysprof-update-to-AdwSpinner.patch
Normal file
53
0004-sysprof-update-to-AdwSpinner.patch
Normal file
@ -0,0 +1,53 @@
|
||||
From 5fc61b27c750788e23f41ed2e87c99cca0dedd9c Mon Sep 17 00:00:00 2001
|
||||
From: Christian Hergert <chergert@redhat.com>
|
||||
Date: Wed, 9 Oct 2024 16:39:13 -0700
|
||||
Subject: [PATCH 04/31] sysprof: update to AdwSpinner
|
||||
|
||||
---
|
||||
src/sysprof/meson.build | 2 +-
|
||||
src/sysprof/sysprof-window.ui | 9 +--------
|
||||
2 files changed, 2 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/src/sysprof/meson.build b/src/sysprof/meson.build
|
||||
index ccd698ea..989bbd11 100644
|
||||
--- a/src/sysprof/meson.build
|
||||
+++ b/src/sysprof/meson.build
|
||||
@@ -85,7 +85,7 @@ sysprof_resources = gnome.compile_resources('sysprof-resources', 'sysprof.gresou
|
||||
sysprof_deps = [
|
||||
cc.find_library('m', required: false),
|
||||
dependency('gtk4', version: gtk_req_version),
|
||||
- dependency('libadwaita-1', version: '>= 1.6.alpha'),
|
||||
+ dependency('libadwaita-1', version: '>= 1.6.0'),
|
||||
dependency('libpanel-1', version: '>= 1.7.0'),
|
||||
|
||||
libsysprof_static_dep,
|
||||
diff --git a/src/sysprof/sysprof-window.ui b/src/sysprof/sysprof-window.ui
|
||||
index b33cd613..1b361e37 100644
|
||||
--- a/src/sysprof/sysprof-window.ui
|
||||
+++ b/src/sysprof/sysprof-window.ui
|
||||
@@ -109,7 +109,7 @@
|
||||
<property name="title-widget">
|
||||
<object class="GtkCenterBox">
|
||||
<child type="start">
|
||||
- <object class="GtkSpinner">
|
||||
+ <object class="AdwSpinner">
|
||||
<binding name="visible">
|
||||
<lookup name="busy" type="SysprofDocument">
|
||||
<lookup name="document" type="SysprofSession">
|
||||
@@ -117,13 +117,6 @@
|
||||
</lookup>
|
||||
</lookup>
|
||||
</binding>
|
||||
- <binding name="spinning">
|
||||
- <lookup name="busy" type="SysprofDocument">
|
||||
- <lookup name="document" type="SysprofSession">
|
||||
- <lookup name="session">SysprofWindow</lookup>
|
||||
- </lookup>
|
||||
- </lookup>
|
||||
- </binding>
|
||||
</object>
|
||||
</child>
|
||||
<child type="center">
|
||||
--
|
||||
2.45.2
|
||||
|
1277
0005-sysprof-add-SysprofDocumentTask-abstraction.patch
Normal file
1277
0005-sysprof-add-SysprofDocumentTask-abstraction.patch
Normal file
File diff suppressed because it is too large
Load Diff
120
0006-libsysprof-add-setup-hooks-for-symbolizers.patch
Normal file
120
0006-libsysprof-add-setup-hooks-for-symbolizers.patch
Normal file
@ -0,0 +1,120 @@
|
||||
From 3633d7b645c4db819cf2263ae32fa63b413c5eb9 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Hergert <chergert@redhat.com>
|
||||
Date: Thu, 10 Oct 2024 17:03:30 -0700
|
||||
Subject: [PATCH 06/31] libsysprof: add setup hooks for symbolizers
|
||||
|
||||
This gives the symbolizer access to the loader so we can propagate tasks
|
||||
back to it.
|
||||
---
|
||||
src/libsysprof/sysprof-multi-symbolizer.c | 22 +++++++++++++++++++++
|
||||
src/libsysprof/sysprof-symbolizer-private.h | 6 +++++-
|
||||
src/libsysprof/sysprof-symbolizer.c | 11 +++++++++++
|
||||
3 files changed, 38 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/libsysprof/sysprof-multi-symbolizer.c b/src/libsysprof/sysprof-multi-symbolizer.c
|
||||
index 483cdde5..e1ad90b0 100644
|
||||
--- a/src/libsysprof/sysprof-multi-symbolizer.c
|
||||
+++ b/src/libsysprof/sysprof-multi-symbolizer.c
|
||||
@@ -27,6 +27,7 @@ struct _SysprofMultiSymbolizer
|
||||
{
|
||||
SysprofSymbolizer parent_instance;
|
||||
GPtrArray *symbolizers;
|
||||
+ guint frozen : 1;
|
||||
};
|
||||
|
||||
struct _SysprofMultiSymbolizerClass
|
||||
@@ -138,6 +139,25 @@ sysprof_multi_symbolizer_symbolize (SysprofSymbolizer *symbolizer,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+static void
|
||||
+sysprof_multi_symbolizer_setup (SysprofSymbolizer *symbolizer,
|
||||
+ SysprofDocumentLoader *loader)
|
||||
+{
|
||||
+ SysprofMultiSymbolizer *self = (SysprofMultiSymbolizer *)symbolizer;
|
||||
+
|
||||
+ g_assert (SYSPROF_IS_MULTI_SYMBOLIZER (self));
|
||||
+ g_assert (SYSPROF_IS_DOCUMENT_LOADER (loader));
|
||||
+
|
||||
+ self->frozen = TRUE;
|
||||
+
|
||||
+ for (guint i = 0; i < self->symbolizers->len; i++)
|
||||
+ {
|
||||
+ SysprofSymbolizer *child = g_ptr_array_index (self->symbolizers, i);
|
||||
+
|
||||
+ _sysprof_symbolizer_setup (child, loader);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static void
|
||||
sysprof_multi_symbolizer_finalize (GObject *object)
|
||||
{
|
||||
@@ -159,6 +179,7 @@ sysprof_multi_symbolizer_class_init (SysprofMultiSymbolizerClass *klass)
|
||||
symbolizer_class->prepare_async = sysprof_multi_symbolizer_prepare_async;
|
||||
symbolizer_class->prepare_finish = sysprof_multi_symbolizer_prepare_finish;
|
||||
symbolizer_class->symbolize = sysprof_multi_symbolizer_symbolize;
|
||||
+ symbolizer_class->setup = sysprof_multi_symbolizer_setup;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -188,6 +209,7 @@ sysprof_multi_symbolizer_take (SysprofMultiSymbolizer *self,
|
||||
g_return_if_fail (SYSPROF_IS_MULTI_SYMBOLIZER (self));
|
||||
g_return_if_fail (SYSPROF_IS_SYMBOLIZER (symbolizer));
|
||||
g_return_if_fail ((gpointer)self != (gpointer)symbolizer);
|
||||
+ g_return_if_fail (self->frozen == FALSE);
|
||||
|
||||
g_ptr_array_add (self->symbolizers, symbolizer);
|
||||
}
|
||||
diff --git a/src/libsysprof/sysprof-symbolizer-private.h b/src/libsysprof/sysprof-symbolizer-private.h
|
||||
index dd917e44..3d68c52b 100644
|
||||
--- a/src/libsysprof/sysprof-symbolizer-private.h
|
||||
+++ b/src/libsysprof/sysprof-symbolizer-private.h
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
#include "sysprof-address-layout-private.h"
|
||||
#include "sysprof-document.h"
|
||||
+#include "sysprof-document-loader.h"
|
||||
#include "sysprof-mount-namespace-private.h"
|
||||
#include "sysprof-process-info-private.h"
|
||||
#include "sysprof-strings-private.h"
|
||||
@@ -41,6 +42,8 @@ struct _SysprofSymbolizerClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
|
||||
+ void (*setup) (SysprofSymbolizer *self,
|
||||
+ SysprofDocumentLoader *loader);
|
||||
void (*prepare_async) (SysprofSymbolizer *self,
|
||||
SysprofDocument *document,
|
||||
GCancellable *cancellable,
|
||||
@@ -56,7 +59,8 @@ struct _SysprofSymbolizerClass
|
||||
SysprofAddress address);
|
||||
};
|
||||
|
||||
-
|
||||
+void _sysprof_symbolizer_setup (SysprofSymbolizer *self,
|
||||
+ SysprofDocumentLoader *loader);
|
||||
void _sysprof_symbolizer_prepare_async (SysprofSymbolizer *self,
|
||||
SysprofDocument *document,
|
||||
GCancellable *cancellable,
|
||||
diff --git a/src/libsysprof/sysprof-symbolizer.c b/src/libsysprof/sysprof-symbolizer.c
|
||||
index 9ad17ca2..47d6021a 100644
|
||||
--- a/src/libsysprof/sysprof-symbolizer.c
|
||||
+++ b/src/libsysprof/sysprof-symbolizer.c
|
||||
@@ -99,3 +99,14 @@ _sysprof_symbolizer_symbolize (SysprofSymbolizer *self,
|
||||
{
|
||||
return SYSPROF_SYMBOLIZER_GET_CLASS (self)->symbolize (self, strings, process_info, context, address);
|
||||
}
|
||||
+
|
||||
+void
|
||||
+_sysprof_symbolizer_setup (SysprofSymbolizer *self,
|
||||
+ SysprofDocumentLoader *loader)
|
||||
+{
|
||||
+ g_return_if_fail (SYSPROF_IS_SYMBOLIZER (self));
|
||||
+ g_return_if_fail (SYSPROF_IS_DOCUMENT_LOADER (loader));
|
||||
+
|
||||
+ if (SYSPROF_SYMBOLIZER_GET_CLASS (self)->setup)
|
||||
+ SYSPROF_SYMBOLIZER_GET_CLASS (self)->setup (self, loader);
|
||||
+}
|
||||
--
|
||||
2.45.2
|
||||
|
159
0007-libsysprof-hoist-fallback-symbol-creation.patch
Normal file
159
0007-libsysprof-hoist-fallback-symbol-creation.patch
Normal file
@ -0,0 +1,159 @@
|
||||
From 271b9abbbca3b334f95cb70141fac9ad2452f3f5 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Hergert <chergert@redhat.com>
|
||||
Date: Thu, 10 Oct 2024 17:04:19 -0700
|
||||
Subject: [PATCH 07/31] libsysprof: hoist fallback symbol creation
|
||||
|
||||
This makes sure that we get that even when not using the Elf symbolizer
|
||||
but also means we can fallback through the Elf symbolizer into the
|
||||
debuginfod symbolizer.
|
||||
---
|
||||
src/libsysprof/sysprof-document-symbols.c | 69 ++++++++++++++++++++++-
|
||||
src/libsysprof/sysprof-elf-symbolizer.c | 24 +-------
|
||||
2 files changed, 69 insertions(+), 24 deletions(-)
|
||||
|
||||
diff --git a/src/libsysprof/sysprof-document-symbols.c b/src/libsysprof/sysprof-document-symbols.c
|
||||
index 2f8d1849..828c7fb6 100644
|
||||
--- a/src/libsysprof/sysprof-document-symbols.c
|
||||
+++ b/src/libsysprof/sysprof-document-symbols.c
|
||||
@@ -85,6 +85,71 @@ symbolize_free (Symbolize *state)
|
||||
g_free (state);
|
||||
}
|
||||
|
||||
+static SysprofSymbol *
|
||||
+do_symbolize (SysprofSymbolizer *symbolizer,
|
||||
+ SysprofStrings *strings,
|
||||
+ SysprofProcessInfo *process_info,
|
||||
+ SysprofAddressContext last_context,
|
||||
+ SysprofAddress address)
|
||||
+{
|
||||
+ SysprofDocumentMmap *map;
|
||||
+ g_autofree char *name = NULL;
|
||||
+ SysprofSymbol *ret;
|
||||
+ const char *nick = NULL;
|
||||
+ const char *path;
|
||||
+ guint64 map_begin;
|
||||
+ guint64 map_end;
|
||||
+ guint64 relative_address;
|
||||
+ guint64 begin_address;
|
||||
+ guint64 end_address;
|
||||
+ guint64 file_offset;
|
||||
+
|
||||
+ if ((ret = _sysprof_symbolizer_symbolize (symbolizer, strings, process_info, last_context, address)))
|
||||
+ return ret;
|
||||
+
|
||||
+ /* Fallback, we failed to locate the symbol within a file we can
|
||||
+ * access, so tell the user about what file contained the symbol
|
||||
+ * and where (relative to that file) the IP was.
|
||||
+ */
|
||||
+
|
||||
+ if (!(map = sysprof_address_layout_lookup (process_info->address_layout, address)))
|
||||
+ return NULL;
|
||||
+
|
||||
+ map_begin = sysprof_document_mmap_get_start_address (map);
|
||||
+ map_end = sysprof_document_mmap_get_end_address (map);
|
||||
+
|
||||
+ g_assert (address >= map_begin);
|
||||
+ g_assert (address < map_end);
|
||||
+
|
||||
+ file_offset = sysprof_document_mmap_get_file_offset (map);
|
||||
+
|
||||
+ relative_address = address;
|
||||
+ relative_address -= map_begin;
|
||||
+ relative_address += file_offset;
|
||||
+
|
||||
+ path = sysprof_document_mmap_get_file (map);
|
||||
+
|
||||
+ begin_address = CLAMP (begin_address, file_offset, file_offset + (map_end - map_begin));
|
||||
+ end_address = CLAMP (end_address, file_offset, file_offset + (map_end - map_begin));
|
||||
+ if (end_address == begin_address)
|
||||
+ end_address++;
|
||||
+
|
||||
+ name = g_strdup_printf ("In File %s+0x%"G_GINT64_MODIFIER"x",
|
||||
+ sysprof_document_mmap_get_file (map),
|
||||
+ relative_address);
|
||||
+ begin_address = address;
|
||||
+ end_address = address + 1;
|
||||
+
|
||||
+ ret = _sysprof_symbol_new (sysprof_strings_get (strings, name),
|
||||
+ sysprof_strings_get (strings, path),
|
||||
+ sysprof_strings_get (strings, nick),
|
||||
+ begin_address, end_address,
|
||||
+ SYSPROF_SYMBOL_KIND_USER);
|
||||
+ ret->is_fallback = TRUE;
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
static void
|
||||
add_traceable (SysprofDocumentSymbols *self,
|
||||
SysprofStrings *strings,
|
||||
@@ -123,7 +188,7 @@ add_traceable (SysprofDocumentSymbols *self,
|
||||
if (sysprof_symbol_cache_lookup (self->kernel_symbols, address) != NULL)
|
||||
continue;
|
||||
|
||||
- if ((symbol = _sysprof_symbolizer_symbolize (symbolizer, strings, process_info, last_context, address)))
|
||||
+ if ((symbol = do_symbolize (symbolizer, strings, process_info, last_context, address)))
|
||||
sysprof_symbol_cache_take (self->kernel_symbols, g_steal_pointer (&symbol));
|
||||
}
|
||||
else
|
||||
@@ -134,7 +199,7 @@ add_traceable (SysprofDocumentSymbols *self,
|
||||
sysprof_symbol_cache_lookup (process_info->symbol_cache, address) != NULL)
|
||||
continue;
|
||||
|
||||
- if ((symbol = _sysprof_symbolizer_symbolize (symbolizer, strings, process_info, last_context, address)))
|
||||
+ if ((symbol = do_symbolize (symbolizer, strings, process_info, last_context, address)))
|
||||
sysprof_symbol_cache_take (process_info->symbol_cache, g_steal_pointer (&symbol));
|
||||
}
|
||||
}
|
||||
diff --git a/src/libsysprof/sysprof-elf-symbolizer.c b/src/libsysprof/sysprof-elf-symbolizer.c
|
||||
index f7aabef7..05bd1d6c 100644
|
||||
--- a/src/libsysprof/sysprof-elf-symbolizer.c
|
||||
+++ b/src/libsysprof/sysprof-elf-symbolizer.c
|
||||
@@ -113,7 +113,7 @@ sysprof_elf_symbolizer_symbolize (SysprofSymbolizer *symbolizer,
|
||||
build_id,
|
||||
file_inode,
|
||||
NULL)))
|
||||
- goto fallback;
|
||||
+ return NULL;
|
||||
|
||||
nick = sysprof_elf_get_nick (elf);
|
||||
|
||||
@@ -124,7 +124,7 @@ sysprof_elf_symbolizer_symbolize (SysprofSymbolizer *symbolizer,
|
||||
relative_address,
|
||||
&begin_address,
|
||||
&end_address)))
|
||||
- goto fallback;
|
||||
+ return NULL;
|
||||
|
||||
/* Sanitize address ranges if we have to. Sometimes that can happen
|
||||
* for us, but it seems to be limited to glibc.
|
||||
@@ -142,26 +142,6 @@ sysprof_elf_symbolizer_symbolize (SysprofSymbolizer *symbolizer,
|
||||
SYSPROF_SYMBOL_KIND_USER);
|
||||
|
||||
return ret;
|
||||
-
|
||||
-fallback:
|
||||
- /* Fallback, we failed to locate the symbol within a file we can
|
||||
- * access, so tell the user about what file contained the symbol
|
||||
- * and where (relative to that file) the IP was.
|
||||
- */
|
||||
- name = g_strdup_printf ("In File %s+0x%"G_GINT64_MODIFIER"x",
|
||||
- sysprof_document_mmap_get_file (map),
|
||||
- relative_address);
|
||||
- begin_address = address;
|
||||
- end_address = address + 1;
|
||||
-
|
||||
- ret = _sysprof_symbol_new (sysprof_strings_get (strings, name),
|
||||
- sysprof_strings_get (strings, path),
|
||||
- sysprof_strings_get (strings, nick),
|
||||
- begin_address, end_address,
|
||||
- SYSPROF_SYMBOL_KIND_USER);
|
||||
- ret->is_fallback = TRUE;
|
||||
-
|
||||
- return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
--
|
||||
2.45.2
|
||||
|
600
0008-libsysprof-add-debuginfod-symbolizer.patch
Normal file
600
0008-libsysprof-add-debuginfod-symbolizer.patch
Normal file
@ -0,0 +1,600 @@
|
||||
From 18f01748814e558f3b2754ef9c541e8e4b2b3fb0 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Hergert <chergert@redhat.com>
|
||||
Date: Thu, 10 Oct 2024 17:07:21 -0700
|
||||
Subject: [PATCH 08/31] libsysprof: add debuginfod symbolizer
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
This is based on a debuginfod_client provided by Barnabás Pőcze in !73.
|
||||
It extends it to use the new task infrastructure to elevate the download
|
||||
process to the user while loading a capture file.
|
||||
---
|
||||
config.h.meson | 2 +
|
||||
meson.build | 2 +
|
||||
meson_options.txt | 2 +
|
||||
src/libsysprof/meson.build | 8 +
|
||||
.../sysprof-debuginfod-symbolizer.c | 229 ++++++++++++++++++
|
||||
.../sysprof-debuginfod-symbolizer.h | 42 ++++
|
||||
.../sysprof-debuginfod-task-private.h | 42 ++++
|
||||
src/libsysprof/sysprof-debuginfod-task.c | 131 ++++++++++
|
||||
src/libsysprof/sysprof-document-loader.c | 15 +-
|
||||
9 files changed, 468 insertions(+), 5 deletions(-)
|
||||
create mode 100644 src/libsysprof/sysprof-debuginfod-symbolizer.c
|
||||
create mode 100644 src/libsysprof/sysprof-debuginfod-symbolizer.h
|
||||
create mode 100644 src/libsysprof/sysprof-debuginfod-task-private.h
|
||||
create mode 100644 src/libsysprof/sysprof-debuginfod-task.c
|
||||
|
||||
diff --git a/config.h.meson b/config.h.meson
|
||||
index d2f7589a..48b3c2c2 100644
|
||||
--- a/config.h.meson
|
||||
+++ b/config.h.meson
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
#mesondefine HAVE_LIBSYSTEMD
|
||||
|
||||
+#mesondefine HAVE_DEBUGINFOD
|
||||
+
|
||||
#mesondefine HAVE_PERF_CLOCKID
|
||||
|
||||
#mesondefine HAVE_POLKIT
|
||||
diff --git a/meson.build b/meson.build
|
||||
index 96c1d093..bac8eae6 100644
|
||||
--- a/meson.build
|
||||
+++ b/meson.build
|
||||
@@ -63,6 +63,7 @@ gio_unix_dep = dependency('gio-unix-2.0', version: glib_req_version,
|
||||
required: need_glib and host_machine.system() != 'windows')
|
||||
gtk_dep = dependency('gtk4', version: gtk_req_version, required: need_gtk)
|
||||
libsystemd_dep = dependency('libsystemd', required: false)
|
||||
+debuginfod_dep = dependency('libdebuginfod', required: get_option('debuginfod'))
|
||||
|
||||
config_h = configuration_data()
|
||||
config_h.set_quoted('API_VERSION_S', libsysprof_api_version.to_string())
|
||||
@@ -99,6 +100,7 @@ config_h.set10('ENABLE_NLS', true)
|
||||
config_h.set_quoted('GETTEXT_PACKAGE', 'sysprof')
|
||||
config_h.set_quoted('PACKAGE_LOCALE_DIR', join_paths(get_option('prefix'), get_option('datadir'), 'locale'))
|
||||
config_h.set10('HAVE_LIBSYSTEMD', libsystemd_dep.found())
|
||||
+config_h.set10('HAVE_DEBUGINFOD', debuginfod_dep.found())
|
||||
|
||||
polkit_agent_dep = dependency('polkit-agent-1', required: get_option('polkit-agent'))
|
||||
config_h.set10('HAVE_POLKIT_AGENT', polkit_agent_dep.found())
|
||||
diff --git a/meson_options.txt b/meson_options.txt
|
||||
index 2f78fc3b..02bb6981 100644
|
||||
--- a/meson_options.txt
|
||||
+++ b/meson_options.txt
|
||||
@@ -49,3 +49,5 @@ option('tests', type: 'boolean')
|
||||
# Optionally disable the examples (this is mostly only useful for building only
|
||||
# libsysprof-capture as a subproject)
|
||||
option('examples', type: 'boolean')
|
||||
+
|
||||
+option('debuginfod', type: 'feature')
|
||||
diff --git a/src/libsysprof/meson.build b/src/libsysprof/meson.build
|
||||
index 697e9665..b4e58078 100644
|
||||
--- a/src/libsysprof/meson.build
|
||||
+++ b/src/libsysprof/meson.build
|
||||
@@ -153,6 +153,13 @@ libsysprof_private_sources = [
|
||||
'timsort/gtktimsort.c',
|
||||
]
|
||||
|
||||
+if debuginfod_dep.found() and get_option('debuginfod').enabled()
|
||||
+ libsysprof_private_sources += [
|
||||
+ 'sysprof-debuginfod-symbolizer.c',
|
||||
+ 'sysprof-debuginfod-task.c'
|
||||
+ ]
|
||||
+endif
|
||||
+
|
||||
if polkit_dep.found()
|
||||
libsysprof_private_sources += ['sysprof-polkit.c']
|
||||
endif
|
||||
@@ -192,6 +199,7 @@ libsysprof_deps = [
|
||||
|
||||
libsystemd_dep,
|
||||
polkit_dep,
|
||||
+ debuginfod_dep,
|
||||
|
||||
libeggbitset_static_dep,
|
||||
libelfparser_static_dep,
|
||||
diff --git a/src/libsysprof/sysprof-debuginfod-symbolizer.c b/src/libsysprof/sysprof-debuginfod-symbolizer.c
|
||||
new file mode 100644
|
||||
index 00000000..8dd60d19
|
||||
--- /dev/null
|
||||
+++ b/src/libsysprof/sysprof-debuginfod-symbolizer.c
|
||||
@@ -0,0 +1,229 @@
|
||||
+/* sysprof-debuginfod-symbolizer.c
|
||||
+ *
|
||||
+ * Copyright 2024 Christian Hergert <chergert@redhat.com>
|
||||
+ *
|
||||
+ * This program is free software: you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License as published by
|
||||
+ * the Free Software Foundation, either version 3 of the License, or
|
||||
+ * (at your option) any later version.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License
|
||||
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
+ *
|
||||
+ * SPDX-License-Identifier: GPL-3.0-or-later
|
||||
+ */
|
||||
+
|
||||
+#include "config.h"
|
||||
+
|
||||
+#include <elfutils/debuginfod.h>
|
||||
+#include <errno.h>
|
||||
+#include <stdatomic.h>
|
||||
+
|
||||
+#include <glib/gstdio.h>
|
||||
+
|
||||
+#include "sysprof-symbolizer-private.h"
|
||||
+#include "sysprof-debuginfod-symbolizer.h"
|
||||
+#include "sysprof-debuginfod-task-private.h"
|
||||
+#include "sysprof-elf-loader-private.h"
|
||||
+#include "sysprof-symbol-private.h"
|
||||
+
|
||||
+struct _SysprofDebuginfodSymbolizer
|
||||
+{
|
||||
+ SysprofSymbolizer parent_instance;
|
||||
+
|
||||
+ GWeakRef loader_wr;
|
||||
+
|
||||
+ debuginfod_client *client;
|
||||
+ SysprofElfLoader *loader;
|
||||
+ GHashTable *cache;
|
||||
+ GHashTable *failed;
|
||||
+};
|
||||
+
|
||||
+struct _SysprofDebuginfodSymbolizerClass
|
||||
+{
|
||||
+ SysprofSymbolizerClass parent_class;
|
||||
+};
|
||||
+
|
||||
+G_DEFINE_FINAL_TYPE (SysprofDebuginfodSymbolizer, sysprof_debuginfod_symbolizer, SYSPROF_TYPE_SYMBOLIZER)
|
||||
+
|
||||
+static SysprofSymbol *
|
||||
+sysprof_debuginfod_symbolizer_symbolize (SysprofSymbolizer *symbolizer,
|
||||
+ SysprofStrings *strings,
|
||||
+ const SysprofProcessInfo *process_info,
|
||||
+ SysprofAddressContext context,
|
||||
+ SysprofAddress address)
|
||||
+{
|
||||
+ SysprofDebuginfodSymbolizer *self = SYSPROF_DEBUGINFOD_SYMBOLIZER (symbolizer);
|
||||
+ g_autoptr(SysprofElf) elf = NULL;
|
||||
+ g_autofree char *name = NULL;
|
||||
+ SysprofSymbol *sym = NULL;
|
||||
+ SysprofDocumentMmap *map;
|
||||
+ const char *build_id;
|
||||
+ const char *path;
|
||||
+ guint64 relative_address;
|
||||
+ guint64 begin_address;
|
||||
+ guint64 end_address;
|
||||
+ guint64 file_offset;
|
||||
+ guint64 map_begin;
|
||||
+ guint64 map_end;
|
||||
+
|
||||
+ if (process_info == NULL ||
|
||||
+ process_info->address_layout == NULL ||
|
||||
+ process_info->mount_namespace == NULL ||
|
||||
+ (context != SYSPROF_ADDRESS_CONTEXT_NONE && context != SYSPROF_ADDRESS_CONTEXT_USER) ||
|
||||
+ !(map = sysprof_address_layout_lookup (process_info->address_layout, address)))
|
||||
+ return NULL;
|
||||
+
|
||||
+ map_begin = sysprof_document_mmap_get_start_address (map);
|
||||
+ map_end = sysprof_document_mmap_get_end_address (map);
|
||||
+
|
||||
+ g_assert (address < map_end);
|
||||
+ g_assert (address >= map_begin);
|
||||
+
|
||||
+ file_offset = sysprof_document_mmap_get_file_offset (map);
|
||||
+ path = sysprof_document_mmap_get_file (map);
|
||||
+
|
||||
+ if (g_hash_table_contains (self->failed, path))
|
||||
+ return NULL;
|
||||
+
|
||||
+ elf = sysprof_elf_loader_load (self->loader,
|
||||
+ process_info->mount_namespace,
|
||||
+ path,
|
||||
+ sysprof_document_mmap_get_build_id (map),
|
||||
+ sysprof_document_mmap_get_file_inode (map),
|
||||
+ NULL);
|
||||
+ if (elf == NULL)
|
||||
+ return NULL;
|
||||
+
|
||||
+ if (!(build_id = sysprof_elf_get_build_id (elf)))
|
||||
+ return NULL;
|
||||
+
|
||||
+ if (!g_hash_table_contains (self->cache, elf))
|
||||
+ {
|
||||
+ g_autoptr(SysprofDebuginfodTask) task = sysprof_debuginfod_task_new ();
|
||||
+ g_autoptr(SysprofDocumentLoader) loader = g_weak_ref_get (&self->loader_wr);
|
||||
+ g_autoptr(SysprofDocumentTaskScope) scope = _sysprof_document_task_register (SYSPROF_DOCUMENT_TASK (task), loader);
|
||||
+ g_autoptr(SysprofElf) debuginfo_elf = NULL;
|
||||
+
|
||||
+ if (!(debuginfo_elf = sysprof_debuginfod_task_find_debuginfo (task, self->client, path, build_id, NULL)))
|
||||
+ {
|
||||
+ g_hash_table_insert (self->failed, g_strdup (path), NULL);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ sysprof_elf_set_debug_link_elf (elf, debuginfo_elf);
|
||||
+
|
||||
+ g_hash_table_insert (self->cache, g_object_ref (elf), NULL);
|
||||
+ }
|
||||
+
|
||||
+ relative_address = address;
|
||||
+ relative_address -= map_begin;
|
||||
+ relative_address += file_offset;
|
||||
+
|
||||
+ name = sysprof_elf_get_symbol_at_address (elf,
|
||||
+ relative_address,
|
||||
+ &begin_address,
|
||||
+ &end_address);
|
||||
+ if (!name)
|
||||
+ return NULL;
|
||||
+
|
||||
+ begin_address = CLAMP (begin_address, file_offset, file_offset + (map_end - map_begin));
|
||||
+ end_address = CLAMP (end_address, file_offset, file_offset + (map_end - map_begin));
|
||||
+ if (end_address == begin_address)
|
||||
+ end_address++;
|
||||
+
|
||||
+ sym = _sysprof_symbol_new (sysprof_strings_get (strings, name),
|
||||
+ sysprof_strings_get (strings, path),
|
||||
+ sysprof_strings_get (strings, sysprof_elf_get_nick (elf)),
|
||||
+ map_begin + (begin_address - file_offset),
|
||||
+ map_begin + (end_address - file_offset),
|
||||
+ SYSPROF_SYMBOL_KIND_USER);
|
||||
+
|
||||
+ return sym;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+sysprof_debuginfod_symbolizer_setup (SysprofSymbolizer *symbolizer,
|
||||
+ SysprofDocumentLoader *loader)
|
||||
+{
|
||||
+ SysprofDebuginfodSymbolizer *self = SYSPROF_DEBUGINFOD_SYMBOLIZER (symbolizer);
|
||||
+
|
||||
+ g_weak_ref_set (&self->loader_wr, loader);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+sysprof_debuginfod_symbolizer_dispose (GObject *object)
|
||||
+{
|
||||
+ SysprofDebuginfodSymbolizer *self = SYSPROF_DEBUGINFOD_SYMBOLIZER (object);
|
||||
+
|
||||
+ g_hash_table_remove_all (self->cache);
|
||||
+
|
||||
+ g_weak_ref_set (&self->loader_wr, NULL);
|
||||
+
|
||||
+ G_OBJECT_CLASS (sysprof_debuginfod_symbolizer_parent_class)->dispose (object);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+sysprof_debuginfod_symbolizer_finalize (GObject *object)
|
||||
+{
|
||||
+ SysprofDebuginfodSymbolizer *self = SYSPROF_DEBUGINFOD_SYMBOLIZER (object);
|
||||
+
|
||||
+ g_clear_object (&self->loader);
|
||||
+
|
||||
+ g_clear_pointer (&self->cache, g_hash_table_unref);
|
||||
+ g_clear_pointer (&self->failed, g_hash_table_unref);
|
||||
+ g_clear_pointer (&self->client, debuginfod_end);
|
||||
+
|
||||
+ g_weak_ref_clear (&self->loader_wr);
|
||||
+
|
||||
+ G_OBJECT_CLASS (sysprof_debuginfod_symbolizer_parent_class)->finalize (object);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+sysprof_debuginfod_symbolizer_class_init (SysprofDebuginfodSymbolizerClass *klass)
|
||||
+{
|
||||
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
+ SysprofSymbolizerClass *symbolizer_class = SYSPROF_SYMBOLIZER_CLASS (klass);
|
||||
+
|
||||
+ object_class->dispose = sysprof_debuginfod_symbolizer_dispose;
|
||||
+ object_class->finalize = sysprof_debuginfod_symbolizer_finalize;
|
||||
+
|
||||
+ symbolizer_class->setup = sysprof_debuginfod_symbolizer_setup;
|
||||
+ symbolizer_class->symbolize = sysprof_debuginfod_symbolizer_symbolize;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+sysprof_debuginfod_symbolizer_init (SysprofDebuginfodSymbolizer *self)
|
||||
+{
|
||||
+ g_weak_ref_init (&self->loader_wr, NULL);
|
||||
+}
|
||||
+
|
||||
+SysprofSymbolizer *
|
||||
+sysprof_debuginfod_symbolizer_new (GError **error)
|
||||
+{
|
||||
+ g_autoptr(SysprofDebuginfodSymbolizer) self = NULL;
|
||||
+
|
||||
+ self = g_object_new (SYSPROF_TYPE_DEBUGINFOD_SYMBOLIZER, NULL);
|
||||
+ self->client = debuginfod_begin ();
|
||||
+
|
||||
+ if (self->client == NULL)
|
||||
+ {
|
||||
+ int errsv = errno;
|
||||
+ g_set_error_literal (error,
|
||||
+ G_IO_ERROR,
|
||||
+ g_io_error_from_errno (errsv),
|
||||
+ g_strerror (errsv));
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ self->loader = sysprof_elf_loader_new ();
|
||||
+ self->cache = g_hash_table_new_full (NULL, NULL, g_object_unref, NULL);
|
||||
+ self->failed = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
|
||||
+
|
||||
+ return SYSPROF_SYMBOLIZER (g_steal_pointer (&self));
|
||||
+}
|
||||
diff --git a/src/libsysprof/sysprof-debuginfod-symbolizer.h b/src/libsysprof/sysprof-debuginfod-symbolizer.h
|
||||
new file mode 100644
|
||||
index 00000000..3a01e566
|
||||
--- /dev/null
|
||||
+++ b/src/libsysprof/sysprof-debuginfod-symbolizer.h
|
||||
@@ -0,0 +1,42 @@
|
||||
+/* sysprof-debuginfod-symbolizer.h
|
||||
+ *
|
||||
+ * Copyright 2024 Christian Hergert <chergert@redhat.com>
|
||||
+ *
|
||||
+ * This program is free software: you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License as published by
|
||||
+ * the Free Software Foundation, either version 3 of the License, or
|
||||
+ * (at your option) any later version.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License
|
||||
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
+ *
|
||||
+ * SPDX-License-Identifier: GPL-3.0-or-later
|
||||
+ */
|
||||
+
|
||||
+#pragma once
|
||||
+
|
||||
+#include "sysprof-symbolizer.h"
|
||||
+
|
||||
+G_BEGIN_DECLS
|
||||
+
|
||||
+#define SYSPROF_TYPE_DEBUGINFOD_SYMBOLIZER (sysprof_debuginfod_symbolizer_get_type())
|
||||
+#define SYSPROF_IS_DEBUGINFOD_SYMBOLIZER(obj) G_TYPE_CHECK_INSTANCE_TYPE(obj, SYSPROF_TYPE_DEBUGINFOD_SYMBOLIZER)
|
||||
+#define SYSPROF_DEBUGINFOD_SYMBOLIZER(obj) G_TYPE_CHECK_INSTANCE_CAST(obj, SYSPROF_TYPE_DEBUGINFOD_SYMBOLIZER, SysprofDebuginfodSymbolizer)
|
||||
+#define SYSPROF_DEBUGINFOD_SYMBOLIZER_CLASS(klass) G_TYPE_CHECK_CLASS_CAST(klass, SYSPROF_TYPE_DEBUGINFOD_SYMBOLIZER, SysprofDebuginfodSymbolizerClass)
|
||||
+
|
||||
+typedef struct _SysprofDebuginfodSymbolizer SysprofDebuginfodSymbolizer;
|
||||
+typedef struct _SysprofDebuginfodSymbolizerClass SysprofDebuginfodSymbolizerClass;
|
||||
+
|
||||
+SYSPROF_AVAILABLE_IN_47
|
||||
+GType sysprof_debuginfod_symbolizer_get_type (void) G_GNUC_CONST;
|
||||
+SYSPROF_AVAILABLE_IN_47
|
||||
+SysprofSymbolizer *sysprof_debuginfod_symbolizer_new (GError **error);
|
||||
+
|
||||
+G_DEFINE_AUTOPTR_CLEANUP_FUNC (SysprofDebuginfodSymbolizer, g_object_unref)
|
||||
+
|
||||
+G_END_DECLS
|
||||
diff --git a/src/libsysprof/sysprof-debuginfod-task-private.h b/src/libsysprof/sysprof-debuginfod-task-private.h
|
||||
new file mode 100644
|
||||
index 00000000..33e595ec
|
||||
--- /dev/null
|
||||
+++ b/src/libsysprof/sysprof-debuginfod-task-private.h
|
||||
@@ -0,0 +1,42 @@
|
||||
+/*
|
||||
+ * sysprof-debuginfod-task-private.h
|
||||
+ *
|
||||
+ * Copyright 2024 Christian Hergert <chergert@redhat.com>
|
||||
+ *
|
||||
+ * This program is free software: you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License as published by
|
||||
+ * the Free Software Foundation, either version 3 of the License, or
|
||||
+ * (at your option) any later version.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License
|
||||
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
+ *
|
||||
+ * SPDX-License-Identifier: GPL-3.0-or-later
|
||||
+ */
|
||||
+
|
||||
+#pragma once
|
||||
+
|
||||
+#include <elfutils/debuginfod.h>
|
||||
+
|
||||
+#include "sysprof-document-task-private.h"
|
||||
+#include "sysprof-elf-private.h"
|
||||
+
|
||||
+G_BEGIN_DECLS
|
||||
+
|
||||
+#define SYSPROF_TYPE_DEBUGINFOD_TASK (sysprof_debuginfod_task_get_type())
|
||||
+
|
||||
+G_DECLARE_FINAL_TYPE (SysprofDebuginfodTask, sysprof_debuginfod_task, SYSPROF, DEBUGINFOD_TASK, SysprofDocumentTask)
|
||||
+
|
||||
+SysprofDebuginfodTask *sysprof_debuginfod_task_new (void);
|
||||
+SysprofElf *sysprof_debuginfod_task_find_debuginfo (SysprofDebuginfodTask *self,
|
||||
+ debuginfod_client *client,
|
||||
+ const char *path,
|
||||
+ const char *build_id_string,
|
||||
+ GError **error);
|
||||
+
|
||||
+G_END_DECLS
|
||||
diff --git a/src/libsysprof/sysprof-debuginfod-task.c b/src/libsysprof/sysprof-debuginfod-task.c
|
||||
new file mode 100644
|
||||
index 00000000..0f996d09
|
||||
--- /dev/null
|
||||
+++ b/src/libsysprof/sysprof-debuginfod-task.c
|
||||
@@ -0,0 +1,131 @@
|
||||
+/*
|
||||
+ * sysprof-debuginfod-task.c
|
||||
+ *
|
||||
+ * Copyright 2024 Christian Hergert <chergert@redhat.com>
|
||||
+ *
|
||||
+ * This program is free software: you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License as published by
|
||||
+ * the Free Software Foundation, either version 3 of the License, or
|
||||
+ * (at your option) any later version.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License
|
||||
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
+ *
|
||||
+ * SPDX-License-Identifier: GPL-3.0-or-later
|
||||
+ */
|
||||
+
|
||||
+#include "config.h"
|
||||
+
|
||||
+#include <glib/gstdio.h>
|
||||
+#include <glib/gi18n.h>
|
||||
+
|
||||
+#include <gio/gio.h>
|
||||
+
|
||||
+#include "sysprof-debuginfod-task-private.h"
|
||||
+
|
||||
+struct _SysprofDebuginfodTask
|
||||
+{
|
||||
+ SysprofDocumentTask parent_instance;
|
||||
+};
|
||||
+
|
||||
+G_DEFINE_FINAL_TYPE (SysprofDebuginfodTask, sysprof_debuginfod_task, SYSPROF_TYPE_DOCUMENT_TASK)
|
||||
+
|
||||
+static void
|
||||
+sysprof_debuginfod_task_class_init (SysprofDebuginfodTaskClass *klass)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+sysprof_debuginfod_task_init (SysprofDebuginfodTask *self)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+SysprofDebuginfodTask *
|
||||
+sysprof_debuginfod_task_new (void)
|
||||
+{
|
||||
+ return g_object_new (SYSPROF_TYPE_DEBUGINFOD_TASK, NULL);
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+sysprof_debuginfod_task_progress_cb (debuginfod_client *client,
|
||||
+ long a,
|
||||
+ long b)
|
||||
+{
|
||||
+ SysprofDocumentTask *task = debuginfod_get_user_data (client);
|
||||
+ double progress;
|
||||
+
|
||||
+ g_assert (client != NULL);
|
||||
+ g_assert (SYSPROF_IS_DEBUGINFOD_TASK (task));
|
||||
+
|
||||
+ if (b > 0)
|
||||
+ progress = (double)a / (double)b;
|
||||
+ else
|
||||
+ progress = 0;
|
||||
+
|
||||
+ _sysprof_document_task_set_progress (task, progress);
|
||||
+
|
||||
+ if (sysprof_document_task_is_cancelled (task))
|
||||
+ return -1;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+SysprofElf *
|
||||
+sysprof_debuginfod_task_find_debuginfo (SysprofDebuginfodTask *self,
|
||||
+ debuginfod_client *client,
|
||||
+ const char *path,
|
||||
+ const char *build_id_string,
|
||||
+ GError **error)
|
||||
+{
|
||||
+ g_autoptr(GMappedFile) mapped_file = NULL;
|
||||
+ g_autoptr(SysprofElf) debuginfo_elf = NULL;
|
||||
+ g_autofd int fd = -1;
|
||||
+ char *debuginfo_path = NULL;
|
||||
+
|
||||
+ g_return_val_if_fail (SYSPROF_IS_DEBUGINFOD_TASK (self), NULL);
|
||||
+ g_return_val_if_fail (client != NULL, NULL);
|
||||
+ g_return_val_if_fail (build_id_string != NULL, NULL);
|
||||
+
|
||||
+ debuginfod_set_user_data (client, self);
|
||||
+ debuginfod_set_progressfn (client, sysprof_debuginfod_task_progress_cb);
|
||||
+
|
||||
+ _sysprof_document_task_set_title (SYSPROF_DOCUMENT_TASK (self), _("Downloading Symbols…"));
|
||||
+ _sysprof_document_task_take_message (SYSPROF_DOCUMENT_TASK (self), g_strdup (path));
|
||||
+
|
||||
+ fd = debuginfod_find_debuginfo (client,
|
||||
+ (const unsigned char *)build_id_string, 0,
|
||||
+ &debuginfo_path);
|
||||
+
|
||||
+ if (fd < 0)
|
||||
+ {
|
||||
+ if (error != NULL)
|
||||
+ {
|
||||
+ int errsv = errno;
|
||||
+ g_set_error_literal (error,
|
||||
+ G_IO_ERROR,
|
||||
+ g_io_error_from_errno (errsv),
|
||||
+ g_strerror (errsv));
|
||||
+ }
|
||||
+
|
||||
+ goto failure;
|
||||
+ }
|
||||
+
|
||||
+ if (!(mapped_file = g_mapped_file_new_from_fd (fd, FALSE, error)))
|
||||
+ goto failure;
|
||||
+
|
||||
+ if (!(debuginfo_elf = sysprof_elf_new (debuginfo_path, g_steal_pointer (&mapped_file), 0, error)))
|
||||
+ goto failure;
|
||||
+
|
||||
+failure:
|
||||
+ free (debuginfo_path);
|
||||
+
|
||||
+ debuginfod_set_user_data (client, NULL);
|
||||
+ debuginfod_set_progressfn (client, NULL);
|
||||
+
|
||||
+ return g_steal_pointer (&debuginfo_elf);
|
||||
+}
|
||||
diff --git a/src/libsysprof/sysprof-document-loader.c b/src/libsysprof/sysprof-document-loader.c
|
||||
index 3cd408c4..00b525df 100644
|
||||
--- a/src/libsysprof/sysprof-document-loader.c
|
||||
+++ b/src/libsysprof/sysprof-document-loader.c
|
||||
@@ -196,7 +196,6 @@ static void
|
||||
set_default_symbolizer (SysprofDocumentLoader *self)
|
||||
{
|
||||
g_autoptr(SysprofMultiSymbolizer) multi = NULL;
|
||||
- g_autoptr(SysprofSymbolizer) debuginfod = NULL;
|
||||
g_autoptr(GError) error = NULL;
|
||||
|
||||
g_assert (SYSPROF_IS_DOCUMENT_LOADER (self));
|
||||
@@ -209,10 +208,16 @@ set_default_symbolizer (SysprofDocumentLoader *self)
|
||||
sysprof_multi_symbolizer_take (multi, sysprof_elf_symbolizer_new ());
|
||||
sysprof_multi_symbolizer_take (multi, sysprof_jitmap_symbolizer_new ());
|
||||
|
||||
- if (!(debuginfod = sysprof_debuginfod_symbolizer_new (&error)))
|
||||
- g_warning ("Failed to create debuginfod symbolizer: %s", error->message);
|
||||
- else
|
||||
- sysprof_multi_symbolizer_take (multi, g_steal_pointer (&debuginfod));
|
||||
+#if HAVE_DEBUGINFOD
|
||||
+ {
|
||||
+ g_autoptr(SysprofSymbolizer) debuginfod = NULL;
|
||||
+
|
||||
+ if (!(debuginfod = sysprof_debuginfod_symbolizer_new (&error)))
|
||||
+ g_warning ("Failed to create debuginfod symbolizer: %s", error->message);
|
||||
+ else
|
||||
+ sysprof_multi_symbolizer_take (multi, g_steal_pointer (&debuginfod));
|
||||
+ }
|
||||
+#endif
|
||||
|
||||
self->symbolizer = SYSPROF_SYMBOLIZER (g_steal_pointer (&multi));
|
||||
}
|
||||
--
|
||||
2.45.2
|
||||
|
26
0009-libsysprof-ensure-access-to-process-info.patch
Normal file
26
0009-libsysprof-ensure-access-to-process-info.patch
Normal file
@ -0,0 +1,26 @@
|
||||
From 9895b74a43dcbb41704572d2304d03d4d24397f2 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Hergert <chergert@redhat.com>
|
||||
Date: Fri, 11 Oct 2024 11:08:52 -0700
|
||||
Subject: [PATCH 09/31] libsysprof: ensure access to process info
|
||||
|
||||
---
|
||||
src/libsysprof/sysprof-document-symbols.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/src/libsysprof/sysprof-document-symbols.c b/src/libsysprof/sysprof-document-symbols.c
|
||||
index 828c7fb6..e5584a69 100644
|
||||
--- a/src/libsysprof/sysprof-document-symbols.c
|
||||
+++ b/src/libsysprof/sysprof-document-symbols.c
|
||||
@@ -112,6 +112,9 @@ do_symbolize (SysprofSymbolizer *symbolizer,
|
||||
* and where (relative to that file) the IP was.
|
||||
*/
|
||||
|
||||
+ if (process_info == NULL || process_info->address_layout == NULL)
|
||||
+ return NULL;
|
||||
+
|
||||
if (!(map = sysprof_address_layout_lookup (process_info->address_layout, address)))
|
||||
return NULL;
|
||||
|
||||
--
|
||||
2.45.2
|
||||
|
25
0010-libsysprof-fix-building-with-Ddebuginfod-auto.patch
Normal file
25
0010-libsysprof-fix-building-with-Ddebuginfod-auto.patch
Normal file
@ -0,0 +1,25 @@
|
||||
From 2c89e348dd469913cf80a1dc4f003aaf5ae7c2ba Mon Sep 17 00:00:00 2001
|
||||
From: Christian Hergert <chergert@redhat.com>
|
||||
Date: Fri, 11 Oct 2024 11:26:13 -0700
|
||||
Subject: [PATCH 10/31] libsysprof: fix building with -Ddebuginfod=auto
|
||||
|
||||
---
|
||||
src/libsysprof/meson.build | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/libsysprof/meson.build b/src/libsysprof/meson.build
|
||||
index b4e58078..ce6e37f2 100644
|
||||
--- a/src/libsysprof/meson.build
|
||||
+++ b/src/libsysprof/meson.build
|
||||
@@ -153,7 +153,7 @@ libsysprof_private_sources = [
|
||||
'timsort/gtktimsort.c',
|
||||
]
|
||||
|
||||
-if debuginfod_dep.found() and get_option('debuginfod').enabled()
|
||||
+if debuginfod_dep.found()
|
||||
libsysprof_private_sources += [
|
||||
'sysprof-debuginfod-symbolizer.c',
|
||||
'sysprof-debuginfod-task.c'
|
||||
--
|
||||
2.45.2
|
||||
|
158
0011-libsysprof-return-NULL-instance-unless-debuginfod-wo.patch
Normal file
158
0011-libsysprof-return-NULL-instance-unless-debuginfod-wo.patch
Normal file
@ -0,0 +1,158 @@
|
||||
From c81b5ae5e690eba77498c3a79db168467641d286 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Hergert <chergert@redhat.com>
|
||||
Date: Fri, 11 Oct 2024 11:45:41 -0700
|
||||
Subject: [PATCH 11/31] libsysprof: return NULL instance unless debuginfod
|
||||
works
|
||||
|
||||
If we are configured with support for debuginfod and it fails to initialize
|
||||
or we are not configured to use debuginfod, always ensure g_object_new()
|
||||
will return a NULL instance back.
|
||||
|
||||
This helps prevent against misconfigured instances so we do not need to
|
||||
do so many checks in vfuncs as well as allowing us to have the GType be
|
||||
available always even when not built with debuginfod.
|
||||
---
|
||||
.../sysprof-debuginfod-symbolizer.c | 66 +++++++++++++++----
|
||||
1 file changed, 53 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/src/libsysprof/sysprof-debuginfod-symbolizer.c b/src/libsysprof/sysprof-debuginfod-symbolizer.c
|
||||
index 8dd60d19..bcad9a5c 100644
|
||||
--- a/src/libsysprof/sysprof-debuginfod-symbolizer.c
|
||||
+++ b/src/libsysprof/sysprof-debuginfod-symbolizer.c
|
||||
@@ -20,18 +20,22 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
-#include <elfutils/debuginfod.h>
|
||||
#include <errno.h>
|
||||
-#include <stdatomic.h>
|
||||
|
||||
#include <glib/gstdio.h>
|
||||
|
||||
#include "sysprof-symbolizer-private.h"
|
||||
#include "sysprof-debuginfod-symbolizer.h"
|
||||
-#include "sysprof-debuginfod-task-private.h"
|
||||
#include "sysprof-elf-loader-private.h"
|
||||
#include "sysprof-symbol-private.h"
|
||||
|
||||
+#if HAVE_DEBUGINFOD
|
||||
+# include <elfutils/debuginfod.h>
|
||||
+# include "sysprof-debuginfod-task-private.h"
|
||||
+#else
|
||||
+typedef struct _debuginfod_client debuginfod_client;
|
||||
+#endif
|
||||
+
|
||||
struct _SysprofDebuginfodSymbolizer
|
||||
{
|
||||
SysprofSymbolizer parent_instance;
|
||||
@@ -58,6 +62,7 @@ sysprof_debuginfod_symbolizer_symbolize (SysprofSymbolizer *symbolizer,
|
||||
SysprofAddressContext context,
|
||||
SysprofAddress address)
|
||||
{
|
||||
+#if HAVE_DEBUGINFOD
|
||||
SysprofDebuginfodSymbolizer *self = SYSPROF_DEBUGINFOD_SYMBOLIZER (symbolizer);
|
||||
g_autoptr(SysprofElf) elf = NULL;
|
||||
g_autofree char *name = NULL;
|
||||
@@ -145,6 +150,9 @@ sysprof_debuginfod_symbolizer_symbolize (SysprofSymbolizer *symbolizer,
|
||||
SYSPROF_SYMBOL_KIND_USER);
|
||||
|
||||
return sym;
|
||||
+#else
|
||||
+ return NULL;
|
||||
+#endif
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -177,19 +185,54 @@ sysprof_debuginfod_symbolizer_finalize (GObject *object)
|
||||
|
||||
g_clear_pointer (&self->cache, g_hash_table_unref);
|
||||
g_clear_pointer (&self->failed, g_hash_table_unref);
|
||||
+
|
||||
+#if HAVE_DEBUGINFOD
|
||||
g_clear_pointer (&self->client, debuginfod_end);
|
||||
+#endif
|
||||
|
||||
g_weak_ref_clear (&self->loader_wr);
|
||||
|
||||
G_OBJECT_CLASS (sysprof_debuginfod_symbolizer_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
+static GObject *
|
||||
+sysprof_debuginfod_symbolizer_constructor (GType type,
|
||||
+ guint n_construct_params,
|
||||
+ GObjectConstructParam *construct_properties)
|
||||
+{
|
||||
+#if HAVE_DEBUGINFOD
|
||||
+ debuginfod_client *client;
|
||||
+ GObject *object;
|
||||
+
|
||||
+ g_assert (type == SYSPROF_TYPE_DEBUGINFOD_SYMBOLIZER);
|
||||
+
|
||||
+ /* Don't even allow creating a SysprofDebuginfodSymbolizer instance unless we
|
||||
+ * can create a new debuginfod_client. This ensures that even if an application
|
||||
+ * does `g_object_new(SYSPROF_TYPE_DEBUGINFOD_SYMBOLIZER, NULL)` they will get
|
||||
+ * `NULL` back instead of a misconfigured instance.
|
||||
+ */
|
||||
+ if (!(client = debuginfod_begin ()))
|
||||
+ return NULL;
|
||||
+
|
||||
+ object = G_OBJECT_CLASS (sysprof_debuginfod_symbolizer_parent_class)
|
||||
+ ->constructor (type, n_construct_params, construct_properties);
|
||||
+
|
||||
+ SYSPROF_DEBUGINFOD_SYMBOLIZER (object)->client = client;
|
||||
+
|
||||
+ return object;
|
||||
+#else
|
||||
+ errno = ENOTSUP;
|
||||
+ return NULL;
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
static void
|
||||
sysprof_debuginfod_symbolizer_class_init (SysprofDebuginfodSymbolizerClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
SysprofSymbolizerClass *symbolizer_class = SYSPROF_SYMBOLIZER_CLASS (klass);
|
||||
|
||||
+ object_class->constructor = sysprof_debuginfod_symbolizer_constructor;
|
||||
object_class->dispose = sysprof_debuginfod_symbolizer_dispose;
|
||||
object_class->finalize = sysprof_debuginfod_symbolizer_finalize;
|
||||
|
||||
@@ -201,17 +244,18 @@ static void
|
||||
sysprof_debuginfod_symbolizer_init (SysprofDebuginfodSymbolizer *self)
|
||||
{
|
||||
g_weak_ref_init (&self->loader_wr, NULL);
|
||||
+
|
||||
+ self->loader = sysprof_elf_loader_new ();
|
||||
+ self->cache = g_hash_table_new_full (NULL, NULL, g_object_unref, NULL);
|
||||
+ self->failed = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
|
||||
}
|
||||
|
||||
SysprofSymbolizer *
|
||||
sysprof_debuginfod_symbolizer_new (GError **error)
|
||||
{
|
||||
- g_autoptr(SysprofDebuginfodSymbolizer) self = NULL;
|
||||
+ SysprofSymbolizer *self;
|
||||
|
||||
- self = g_object_new (SYSPROF_TYPE_DEBUGINFOD_SYMBOLIZER, NULL);
|
||||
- self->client = debuginfod_begin ();
|
||||
-
|
||||
- if (self->client == NULL)
|
||||
+ if (!(self = g_object_new (SYSPROF_TYPE_DEBUGINFOD_SYMBOLIZER, NULL)))
|
||||
{
|
||||
int errsv = errno;
|
||||
g_set_error_literal (error,
|
||||
@@ -221,9 +265,5 @@ sysprof_debuginfod_symbolizer_new (GError **error)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- self->loader = sysprof_elf_loader_new ();
|
||||
- self->cache = g_hash_table_new_full (NULL, NULL, g_object_unref, NULL);
|
||||
- self->failed = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
|
||||
-
|
||||
- return SYSPROF_SYMBOLIZER (g_steal_pointer (&self));
|
||||
+ return self;
|
||||
}
|
||||
--
|
||||
2.45.2
|
||||
|
56
0012-build-always-build-debuginfod-symbolizer.patch
Normal file
56
0012-build-always-build-debuginfod-symbolizer.patch
Normal file
@ -0,0 +1,56 @@
|
||||
From e15c1147f1543af5900f1caa8c1adf41a52a8a68 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Hergert <chergert@redhat.com>
|
||||
Date: Fri, 11 Oct 2024 11:46:26 -0700
|
||||
Subject: [PATCH 12/31] build: always build debuginfod symbolizer
|
||||
|
||||
Even if it is disabled, we want the GType enabled and part of our ABI. We
|
||||
will return NULL if one is created and debuginfod is not supported or if
|
||||
we failed to create a client.
|
||||
---
|
||||
src/libsysprof/meson.build | 3 ++-
|
||||
src/libsysprof/sysprof.h | 1 +
|
||||
2 files changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/libsysprof/meson.build b/src/libsysprof/meson.build
|
||||
index ce6e37f2..549042de 100644
|
||||
--- a/src/libsysprof/meson.build
|
||||
+++ b/src/libsysprof/meson.build
|
||||
@@ -10,6 +10,7 @@ libsysprof_public_sources = [
|
||||
'sysprof-cpu-info.c',
|
||||
'sysprof-cpu-usage.c',
|
||||
'sysprof-dbus-monitor.c',
|
||||
+ 'sysprof-debuginfod-symbolizer.c',
|
||||
'sysprof-diagnostic.c',
|
||||
'sysprof-disk-usage.c',
|
||||
'sysprof-document-allocation.c',
|
||||
@@ -75,6 +76,7 @@ libsysprof_public_headers = [
|
||||
'sysprof-cpu-info.h',
|
||||
'sysprof-cpu-usage.h',
|
||||
'sysprof-dbus-monitor.h',
|
||||
+ 'sysprof-debuginfod-symbolizer.h',
|
||||
'sysprof-diagnostic.h',
|
||||
'sysprof-disk-usage.h',
|
||||
'sysprof-document-allocation.h',
|
||||
@@ -155,7 +157,6 @@ libsysprof_private_sources = [
|
||||
|
||||
if debuginfod_dep.found()
|
||||
libsysprof_private_sources += [
|
||||
- 'sysprof-debuginfod-symbolizer.c',
|
||||
'sysprof-debuginfod-task.c'
|
||||
]
|
||||
endif
|
||||
diff --git a/src/libsysprof/sysprof.h b/src/libsysprof/sysprof.h
|
||||
index c2176619..d30f9fd4 100644
|
||||
--- a/src/libsysprof/sysprof.h
|
||||
+++ b/src/libsysprof/sysprof.h
|
||||
@@ -34,6 +34,7 @@ G_BEGIN_DECLS
|
||||
# include "sysprof-cpu-info.h"
|
||||
# include "sysprof-cpu-usage.h"
|
||||
# include "sysprof-dbus-monitor.h"
|
||||
+# include "sysprof-debuginfod-symbolizer.h"
|
||||
# include "sysprof-diagnostic.h"
|
||||
# include "sysprof-disk-usage.h"
|
||||
# include "sysprof-document-allocation.h"
|
||||
--
|
||||
2.45.2
|
||||
|
49
0013-libsysprof-remove-unnecessary-address-calculation.patch
Normal file
49
0013-libsysprof-remove-unnecessary-address-calculation.patch
Normal file
@ -0,0 +1,49 @@
|
||||
From 2f9eb12a3348ae41d51bbeb56fd293c5204b7851 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Hergert <chergert@redhat.com>
|
||||
Date: Wed, 23 Oct 2024 11:54:33 -0700
|
||||
Subject: [PATCH 13/31] libsysprof: remove unnecessary address calculation
|
||||
|
||||
We are only fallback symbols here, which is 1 address-wide.
|
||||
---
|
||||
src/libsysprof/sysprof-document-symbols.c | 11 +----------
|
||||
1 file changed, 1 insertion(+), 10 deletions(-)
|
||||
|
||||
diff --git a/src/libsysprof/sysprof-document-symbols.c b/src/libsysprof/sysprof-document-symbols.c
|
||||
index e5584a69..642f702b 100644
|
||||
--- a/src/libsysprof/sysprof-document-symbols.c
|
||||
+++ b/src/libsysprof/sysprof-document-symbols.c
|
||||
@@ -100,8 +100,6 @@ do_symbolize (SysprofSymbolizer *symbolizer,
|
||||
guint64 map_begin;
|
||||
guint64 map_end;
|
||||
guint64 relative_address;
|
||||
- guint64 begin_address;
|
||||
- guint64 end_address;
|
||||
guint64 file_offset;
|
||||
|
||||
if ((ret = _sysprof_symbolizer_symbolize (symbolizer, strings, process_info, last_context, address)))
|
||||
@@ -132,21 +130,14 @@ do_symbolize (SysprofSymbolizer *symbolizer,
|
||||
|
||||
path = sysprof_document_mmap_get_file (map);
|
||||
|
||||
- begin_address = CLAMP (begin_address, file_offset, file_offset + (map_end - map_begin));
|
||||
- end_address = CLAMP (end_address, file_offset, file_offset + (map_end - map_begin));
|
||||
- if (end_address == begin_address)
|
||||
- end_address++;
|
||||
-
|
||||
name = g_strdup_printf ("In File %s+0x%"G_GINT64_MODIFIER"x",
|
||||
sysprof_document_mmap_get_file (map),
|
||||
relative_address);
|
||||
- begin_address = address;
|
||||
- end_address = address + 1;
|
||||
|
||||
ret = _sysprof_symbol_new (sysprof_strings_get (strings, name),
|
||||
sysprof_strings_get (strings, path),
|
||||
sysprof_strings_get (strings, nick),
|
||||
- begin_address, end_address,
|
||||
+ address, address + 1,
|
||||
SYSPROF_SYMBOL_KIND_USER);
|
||||
ret->is_fallback = TRUE;
|
||||
|
||||
--
|
||||
2.45.2
|
||||
|
251
0014-libsysprof-add-muxer-GSource.patch
Normal file
251
0014-libsysprof-add-muxer-GSource.patch
Normal file
@ -0,0 +1,251 @@
|
||||
From 917b05544e46282ee3d77dcd4ab050df5f80a1d3 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Hergert <chergert@redhat.com>
|
||||
Date: Fri, 25 Oct 2024 10:49:15 -0700
|
||||
Subject: [PATCH 14/31] libsysprof: add muxer GSource
|
||||
|
||||
This allows copying events from a capture stream transparently into the
|
||||
destination. No processing of the stream is performed, but that may change
|
||||
in the future to accomidate JIT/Counter translations.
|
||||
|
||||
Internal only as support for upcoming live unwinding via external process.
|
||||
---
|
||||
src/libsysprof/meson.build | 1 +
|
||||
src/libsysprof/sysprof-muxer-source.c | 173 ++++++++++++++++++++++++++
|
||||
src/libsysprof/sysprof-muxer-source.h | 33 +++++
|
||||
3 files changed, 207 insertions(+)
|
||||
create mode 100644 src/libsysprof/sysprof-muxer-source.c
|
||||
create mode 100644 src/libsysprof/sysprof-muxer-source.h
|
||||
|
||||
diff --git a/src/libsysprof/meson.build b/src/libsysprof/meson.build
|
||||
index 549042de..f3fa0850 100644
|
||||
--- a/src/libsysprof/meson.build
|
||||
+++ b/src/libsysprof/meson.build
|
||||
@@ -147,6 +147,7 @@ libsysprof_private_sources = [
|
||||
'sysprof-mount-device.c',
|
||||
'sysprof-mount-namespace.c',
|
||||
'sysprof-mount.c',
|
||||
+ 'sysprof-muxer-source.c',
|
||||
'sysprof-perf-event-stream.c',
|
||||
'sysprof-podman.c',
|
||||
'sysprof-process-info.c',
|
||||
diff --git a/src/libsysprof/sysprof-muxer-source.c b/src/libsysprof/sysprof-muxer-source.c
|
||||
new file mode 100644
|
||||
index 00000000..c037a38f
|
||||
--- /dev/null
|
||||
+++ b/src/libsysprof/sysprof-muxer-source.c
|
||||
@@ -0,0 +1,173 @@
|
||||
+/*
|
||||
+ * sysprof-muxer-source.c
|
||||
+ *
|
||||
+ * Copyright 2024 Christian Hergert <chergert@redhat.com>
|
||||
+ *
|
||||
+ * This program is free software: you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License as published by
|
||||
+ * the Free Software Foundation, either version 3 of the License, or
|
||||
+ * (at your option) any later version.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License
|
||||
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
+ *
|
||||
+ * SPDX-License-Identifier: GPL-3.0-or-later
|
||||
+ */
|
||||
+
|
||||
+#include "config.h"
|
||||
+
|
||||
+#include <glib/gstdio.h>
|
||||
+#include <glib-unix.h>
|
||||
+
|
||||
+#include "sysprof-muxer-source.h"
|
||||
+
|
||||
+#define DEFAULT_BUFFER_SIZE (4096*16)
|
||||
+
|
||||
+typedef struct _SysprofMuxerSource
|
||||
+{
|
||||
+ GSource gsource;
|
||||
+ int capture_fd;
|
||||
+ SysprofCaptureWriter *writer;
|
||||
+ struct {
|
||||
+ guint8 *allocation;
|
||||
+ guint8 *begin;
|
||||
+ guint8 *end;
|
||||
+ guint8 *capacity;
|
||||
+ gsize to_skip;
|
||||
+ } buffer;
|
||||
+} SysprofMuxerSource;
|
||||
+
|
||||
+static gboolean
|
||||
+sysprof_muxer_source_size (SysprofMuxerSource *source)
|
||||
+{
|
||||
+ return source->buffer.end - source->buffer.begin;
|
||||
+}
|
||||
+
|
||||
+static gboolean
|
||||
+sysprof_muxer_source_dispatch (GSource *gsource,
|
||||
+ GSourceFunc callback,
|
||||
+ gpointer user_data)
|
||||
+{
|
||||
+ SysprofMuxerSource *source = (SysprofMuxerSource *)gsource;
|
||||
+ gssize n_read;
|
||||
+
|
||||
+ g_assert (source != NULL);
|
||||
+ g_assert (source->writer != NULL);
|
||||
+
|
||||
+ /* Try to read the next chunk */
|
||||
+ n_read = read (source->capture_fd, source->buffer.end, source->buffer.capacity - source->buffer.end);
|
||||
+
|
||||
+ if (n_read > 0)
|
||||
+ {
|
||||
+ const SysprofCaptureFrame *frame;
|
||||
+
|
||||
+ /* Advance tail to what was filled */
|
||||
+ source->buffer.end += n_read;
|
||||
+
|
||||
+ /* Get to next alignment */
|
||||
+ if (source->buffer.to_skip)
|
||||
+ {
|
||||
+ gsize amount = MIN (source->buffer.to_skip, source->buffer.end - source->buffer.begin);
|
||||
+ source->buffer.begin += amount;
|
||||
+ source->buffer.to_skip -= amount;
|
||||
+ }
|
||||
+
|
||||
+ /* If there is enough to read the frame header, try to read and dispatch
|
||||
+ * it in raw form. We assume we're the same endianness here because this
|
||||
+ * is coming from the same host (live-unwinder currently).
|
||||
+ */
|
||||
+ while (sysprof_muxer_source_size (source) >= sizeof *frame)
|
||||
+ {
|
||||
+ frame = (const SysprofCaptureFrame *)source->buffer.begin;
|
||||
+
|
||||
+ if (frame->len <= sysprof_muxer_source_size (source))
|
||||
+ {
|
||||
+ source->buffer.begin += frame->len;
|
||||
+
|
||||
+ if (frame->len % sizeof (guint64) != 0)
|
||||
+ source->buffer.to_skip = sizeof (guint64) - (frame->len % sizeof (guint64));
|
||||
+
|
||||
+ /* TODO: Technically for counters/JIT map we need to translate them. */
|
||||
+
|
||||
+ _sysprof_capture_writer_add_raw (source->writer, frame);
|
||||
+ }
|
||||
+
|
||||
+ if (source->buffer.to_skip > 0 &&
|
||||
+ source->buffer.to_skip <= sysprof_muxer_source_size (source))
|
||||
+ {
|
||||
+ source->buffer.begin += source->buffer.to_skip;
|
||||
+ source->buffer.to_skip = 0;
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ /* Move anything left to the head of the buffer so we can
|
||||
+ * fill in the entire next frame of data.
|
||||
+ */
|
||||
+ if (source->buffer.begin < source->buffer.end)
|
||||
+ {
|
||||
+ /* TODO: Should we adjust for alignment here? */
|
||||
+
|
||||
+ memmove (source->buffer.allocation,
|
||||
+ source->buffer.begin,
|
||||
+ source->buffer.end - source->buffer.begin);
|
||||
+ source->buffer.end = source->buffer.allocation + (source->buffer.end - source->buffer.begin);
|
||||
+ source->buffer.begin = source->buffer.allocation;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ source->buffer.end = source->buffer.allocation;
|
||||
+ source->buffer.begin = source->buffer.allocation;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ return G_SOURCE_CONTINUE;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+sysprof_muxer_source_finalize (GSource *gsource)
|
||||
+{
|
||||
+ SysprofMuxerSource *source = (SysprofMuxerSource *)gsource;
|
||||
+
|
||||
+ g_clear_fd (&source->capture_fd, NULL);
|
||||
+ g_clear_pointer (&source->writer, sysprof_capture_writer_unref);
|
||||
+ g_clear_pointer (&source->buffer.begin, g_free);
|
||||
+}
|
||||
+
|
||||
+static const GSourceFuncs source_funcs = {
|
||||
+ .dispatch = sysprof_muxer_source_dispatch,
|
||||
+ .finalize = sysprof_muxer_source_finalize,
|
||||
+};
|
||||
+
|
||||
+GSource *
|
||||
+sysprof_muxer_source_new (int capture_fd,
|
||||
+ SysprofCaptureWriter *writer)
|
||||
+{
|
||||
+ SysprofMuxerSource *source;
|
||||
+
|
||||
+ g_return_val_if_fail (capture_fd > -1, NULL);
|
||||
+ g_return_val_if_fail (writer != NULL, NULL);
|
||||
+
|
||||
+ source = (SysprofMuxerSource *)g_source_new ((GSourceFuncs *)&source_funcs, sizeof (SysprofMuxerSource));
|
||||
+ source->capture_fd = capture_fd;
|
||||
+ source->writer = sysprof_capture_writer_ref (writer);
|
||||
+ source->buffer.allocation = g_malloc (DEFAULT_BUFFER_SIZE);
|
||||
+ source->buffer.begin = source->buffer.allocation;
|
||||
+ source->buffer.end = source->buffer.allocation;
|
||||
+ source->buffer.capacity = source->buffer.allocation + DEFAULT_BUFFER_SIZE;
|
||||
+ source->buffer.to_skip = sizeof (SysprofCaptureFileHeader);
|
||||
+
|
||||
+ g_unix_set_fd_nonblocking (capture_fd, TRUE, NULL);
|
||||
+
|
||||
+ g_source_add_unix_fd ((GSource *)source, capture_fd, G_IO_IN);
|
||||
+
|
||||
+ return (GSource *)source;
|
||||
+}
|
||||
diff --git a/src/libsysprof/sysprof-muxer-source.h b/src/libsysprof/sysprof-muxer-source.h
|
||||
new file mode 100644
|
||||
index 00000000..9b9a94e1
|
||||
--- /dev/null
|
||||
+++ b/src/libsysprof/sysprof-muxer-source.h
|
||||
@@ -0,0 +1,33 @@
|
||||
+/*
|
||||
+ * sysprof-muxer-source.h
|
||||
+ *
|
||||
+ * Copyright 2024 Christian Hergert <chergert@redhat.com>
|
||||
+ *
|
||||
+ * This program is free software: you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License as published by
|
||||
+ * the Free Software Foundation, either version 3 of the License, or
|
||||
+ * (at your option) any later version.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License
|
||||
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
+ *
|
||||
+ * SPDX-License-Identifier: GPL-3.0-or-later
|
||||
+ */
|
||||
+
|
||||
+#pragma once
|
||||
+
|
||||
+#include <glib.h>
|
||||
+
|
||||
+#include <sysprof-capture.h>
|
||||
+
|
||||
+G_BEGIN_DECLS
|
||||
+
|
||||
+GSource *sysprof_muxer_source_new (int capture_fd,
|
||||
+ SysprofCaptureWriter *writer);
|
||||
+
|
||||
+G_END_DECLS
|
||||
--
|
||||
2.45.2
|
||||
|
138
0015-libsysprof-add-support-for-stack-regs-options-in-att.patch
Normal file
138
0015-libsysprof-add-support-for-stack-regs-options-in-att.patch
Normal file
@ -0,0 +1,138 @@
|
||||
From 4583026b751c3d00294ecec6ed1be11dcaf17623 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Hergert <chergert@redhat.com>
|
||||
Date: Sun, 3 Nov 2024 10:39:23 -0800
|
||||
Subject: [PATCH 15/31] 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
|
||||
|
2787
0016-sysprofd-add-support-for-unwinding-without-frame-poi.patch
Normal file
2787
0016-sysprofd-add-support-for-unwinding-without-frame-poi.patch
Normal file
File diff suppressed because it is too large
Load Diff
694
0017-libsysprof-add-SysprofUserSampler-for-live-unwinding.patch
Normal file
694
0017-libsysprof-add-SysprofUserSampler-for-live-unwinding.patch
Normal file
@ -0,0 +1,694 @@
|
||||
From a58aa3b33173e5fab8ec81b6b2961e2113ea716b Mon Sep 17 00:00:00 2001
|
||||
From: Christian Hergert <chergert@redhat.com>
|
||||
Date: Sun, 3 Nov 2024 10:53:29 -0800
|
||||
Subject: [PATCH 17/31] libsysprof: add SysprofUserSampler for live unwinding
|
||||
|
||||
This instrument triggers the live unwinder in sysprofd to capture a
|
||||
pre-configured amount of stack contents and CPU registers. You can use
|
||||
this instead of SysprofSampler in cases where you do not have frame-
|
||||
pointers but want a useful trace.
|
||||
|
||||
It does have a moderate amount of CPU overhead compared to just relying
|
||||
on frame-pointers so keep that in mind. Generally useful on platforms
|
||||
that do not have frame pointers such as CentOS.
|
||||
---
|
||||
src/libsysprof/meson.build | 7 +
|
||||
src/libsysprof/sysprof-user-sampler.c | 570 ++++++++++++++++++++++++++
|
||||
src/libsysprof/sysprof-user-sampler.h | 43 ++
|
||||
src/libsysprof/sysprof.h | 1 +
|
||||
4 files changed, 621 insertions(+)
|
||||
create mode 100644 src/libsysprof/sysprof-user-sampler.c
|
||||
create mode 100644 src/libsysprof/sysprof-user-sampler.h
|
||||
|
||||
diff --git a/src/libsysprof/meson.build b/src/libsysprof/meson.build
|
||||
index f3fa0850..e49c3a37 100644
|
||||
--- a/src/libsysprof/meson.build
|
||||
+++ b/src/libsysprof/meson.build
|
||||
@@ -63,6 +63,7 @@ libsysprof_public_sources = [
|
||||
'sysprof-time-span.c',
|
||||
'sysprof-tracefd-consumer.c',
|
||||
'sysprof-tracer.c',
|
||||
+ 'sysprof-user-sampler.c',
|
||||
]
|
||||
|
||||
libsysprof_public_headers = [
|
||||
@@ -130,6 +131,7 @@ libsysprof_public_headers = [
|
||||
'sysprof-time-span.h',
|
||||
'sysprof-tracefd-consumer.h',
|
||||
'sysprof-tracer.h',
|
||||
+ 'sysprof-user-sampler.h',
|
||||
]
|
||||
|
||||
libsysprof_private_sources = [
|
||||
@@ -154,6 +156,11 @@ libsysprof_private_sources = [
|
||||
'sysprof-strings.c',
|
||||
'sysprof-symbol-cache.c',
|
||||
'timsort/gtktimsort.c',
|
||||
+
|
||||
+ gnome.gdbus_codegen('ipc-unwinder',
|
||||
+ sources: '../sysprofd/org.gnome.Sysprof3.Unwinder.xml',
|
||||
+ interface_prefix: 'org.gnome.Sysprof3.',
|
||||
+ namespace: 'Ipc'),
|
||||
]
|
||||
|
||||
if debuginfod_dep.found()
|
||||
diff --git a/src/libsysprof/sysprof-user-sampler.c b/src/libsysprof/sysprof-user-sampler.c
|
||||
new file mode 100644
|
||||
index 00000000..0e3afeae
|
||||
--- /dev/null
|
||||
+++ b/src/libsysprof/sysprof-user-sampler.c
|
||||
@@ -0,0 +1,570 @@
|
||||
+/* sysprof-user-sampler.c
|
||||
+ *
|
||||
+ * Copyright 2023 Christian Hergert <chergert@redhat.com>
|
||||
+ *
|
||||
+ * This program is free software: you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License as published by
|
||||
+ * the Free Software Foundation, either version 3 of the License, or
|
||||
+ * (at your option) any later version.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License
|
||||
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
+ *
|
||||
+ * SPDX-License-Identifier: GPL-3.0-or-later
|
||||
+ */
|
||||
+
|
||||
+#include "config.h"
|
||||
+
|
||||
+#include <sys/ioctl.h>
|
||||
+#include <sys/eventfd.h>
|
||||
+
|
||||
+#include <asm/perf_regs.h>
|
||||
+
|
||||
+#include <glib/gstdio.h>
|
||||
+
|
||||
+#include "sysprof-instrument-private.h"
|
||||
+#include "sysprof-perf-event-stream-private.h"
|
||||
+#include "sysprof-recording-private.h"
|
||||
+#include "sysprof-user-sampler.h"
|
||||
+#include "sysprof-muxer-source.h"
|
||||
+
|
||||
+#include "ipc-unwinder.h"
|
||||
+
|
||||
+/* The following was provided to Sysprof by Serhei Makarov as part
|
||||
+ * of the eu-stacktrace prototype work.
|
||||
+ */
|
||||
+#ifdef _ASM_X86_PERF_REGS_H
|
||||
+/* #define SYSPROF_ARCH_PREFERRED_REGS PERF_REG_EXTENDED_MASK -- error on x86_64 due to including segment regs*/
|
||||
+#define REG(R) (1ULL << PERF_REG_X86_ ## R)
|
||||
+#define DWARF_NEEDED_REGS (/* no FLAGS */ REG(IP) | REG(SP) | REG(AX) | REG(CX) | REG(DX) | REG(BX) | REG(SI) | REG(DI) | REG(SP) | REG(BP) | /* no segment regs */ REG(R8) | REG(R9) | REG(R10) | REG(R11) | REG(R12) | REG(R13) | REG(R14) | REG(R15))
|
||||
+/* XXX register ordering is defined in linux arch/x86/include/uapi/asm/perf_regs.h;
|
||||
+ see code in tools/perf/util/intel-pt.c intel_pt_add_gp_regs()
|
||||
+ and note how registers are added in the same order as the perf_regs.h enum */
|
||||
+#define SYSPROF_ARCH_PREFERRED_REGS DWARF_NEEDED_REGS
|
||||
+/* TODO: add other architectures, imitating the linux tools/perf tree */
|
||||
+#else
|
||||
+# define SYSPROF_ARCH_PREFERRED_REGS PERF_REG_EXTENDED_MASK
|
||||
+#endif /* _ASM_{arch}_PERF_REGS_H */
|
||||
+
|
||||
+#define N_WAKEUP_EVENTS 149
|
||||
+
|
||||
+struct _SysprofUserSampler
|
||||
+{
|
||||
+ SysprofInstrument parent_instance;
|
||||
+ GArray *perf_fds;
|
||||
+ int capture_fd;
|
||||
+ int event_fd;
|
||||
+ guint stack_size;
|
||||
+};
|
||||
+
|
||||
+struct _SysprofUserSamplerClass
|
||||
+{
|
||||
+ SysprofInstrumentClass parent_class;
|
||||
+};
|
||||
+
|
||||
+G_DEFINE_FINAL_TYPE (SysprofUserSampler, sysprof_user_sampler, SYSPROF_TYPE_INSTRUMENT)
|
||||
+
|
||||
+static void
|
||||
+close_fd (gpointer data)
|
||||
+{
|
||||
+ int *fdp = data;
|
||||
+
|
||||
+ if (*fdp != -1)
|
||||
+ {
|
||||
+ close (*fdp);
|
||||
+ *fdp = -1;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+sysprof_user_sampler_ioctl (SysprofUserSampler *self,
|
||||
+ gboolean enable)
|
||||
+{
|
||||
+ for (guint i = 0; i < self->perf_fds->len; i++)
|
||||
+ {
|
||||
+ int perf_fd = g_array_index (self->perf_fds, int, i);
|
||||
+
|
||||
+ if (0 != ioctl (perf_fd, enable ? PERF_EVENT_IOC_ENABLE : PERF_EVENT_IOC_DISABLE))
|
||||
+ {
|
||||
+ int errsv = errno;
|
||||
+ g_warning ("Failed to toggle perf_fd: %s", g_strerror (errsv));
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static char **
|
||||
+sysprof_user_sampler_list_required_policy (SysprofInstrument *instrument)
|
||||
+{
|
||||
+ static const char *policy[] = {"org.gnome.sysprof3.profile", NULL};
|
||||
+
|
||||
+ return g_strdupv ((char **)policy);
|
||||
+}
|
||||
+
|
||||
+typedef struct _Prepare
|
||||
+{
|
||||
+ SysprofRecording *recording;
|
||||
+ SysprofUserSampler *sampler;
|
||||
+ guint stack_size;
|
||||
+} Prepare;
|
||||
+
|
||||
+static void
|
||||
+prepare_free (Prepare *prepare)
|
||||
+{
|
||||
+ g_clear_object (&prepare->recording);
|
||||
+ g_clear_object (&prepare->sampler);
|
||||
+ g_free (prepare);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+_perf_event_open_cb (GObject *object,
|
||||
+ GAsyncResult *result,
|
||||
+ gpointer user_data)
|
||||
+{
|
||||
+ GDBusConnection *connection = (GDBusConnection *)object;
|
||||
+ g_autoptr(DexPromise) promise = user_data;
|
||||
+ g_autoptr(GUnixFDList) fd_list = NULL;
|
||||
+ g_autoptr(GVariant) ret = NULL;
|
||||
+ g_autoptr(GError) error = NULL;
|
||||
+
|
||||
+ g_assert (G_IS_DBUS_CONNECTION (connection));
|
||||
+ g_assert (G_IS_ASYNC_RESULT (result));
|
||||
+ g_assert (DEX_IS_PROMISE (promise));
|
||||
+
|
||||
+ if ((ret = g_dbus_connection_call_with_unix_fd_list_finish (connection, &fd_list, result, &error)))
|
||||
+ {
|
||||
+ g_autofd int fd = -1;
|
||||
+ int handle;
|
||||
+
|
||||
+ g_variant_get (ret, "(h)", &handle);
|
||||
+
|
||||
+ if (-1 == (fd = g_unix_fd_list_get (fd_list, handle, &error)))
|
||||
+ goto failure;
|
||||
+
|
||||
+ dex_promise_resolve_fd (promise, g_steal_fd (&fd));
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+failure:
|
||||
+ dex_promise_reject (promise, g_steal_pointer (&error));
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+_perf_event_open (GDBusConnection *connection,
|
||||
+ int cpu,
|
||||
+ guint stack_size,
|
||||
+ GError **error)
|
||||
+{
|
||||
+ g_autoptr(DexPromise) promise = NULL;
|
||||
+ g_autoptr(GVariant) options = NULL;
|
||||
+ g_autofd int perf_fd = -1;
|
||||
+ struct perf_event_attr attr = {0};
|
||||
+ gboolean with_mmap2 = TRUE;
|
||||
+ gboolean use_software = FALSE;
|
||||
+
|
||||
+ g_assert (G_IS_DBUS_CONNECTION (connection));
|
||||
+
|
||||
+try_again:
|
||||
+ attr.sample_type = PERF_SAMPLE_IP
|
||||
+ | PERF_SAMPLE_TID
|
||||
+ | PERF_SAMPLE_IDENTIFIER
|
||||
+ | PERF_SAMPLE_CALLCHAIN
|
||||
+ | PERF_SAMPLE_STACK_USER
|
||||
+ | PERF_SAMPLE_REGS_USER
|
||||
+ | PERF_SAMPLE_TIME;
|
||||
+ attr.wakeup_events = N_WAKEUP_EVENTS;
|
||||
+ attr.disabled = TRUE;
|
||||
+ attr.mmap = TRUE;
|
||||
+ attr.mmap2 = with_mmap2;
|
||||
+ attr.comm = 1;
|
||||
+ attr.task = 1;
|
||||
+ attr.exclude_idle = 1;
|
||||
+ attr.sample_id_all = 1;
|
||||
+
|
||||
+#ifdef HAVE_PERF_CLOCKID
|
||||
+ attr.clockid = sysprof_clock;
|
||||
+ attr.use_clockid = 1;
|
||||
+#endif
|
||||
+
|
||||
+ attr.sample_stack_user = stack_size;
|
||||
+ attr.sample_regs_user = SYSPROF_ARCH_PREFERRED_REGS;
|
||||
+
|
||||
+ attr.size = sizeof attr;
|
||||
+
|
||||
+ if (use_software)
|
||||
+ {
|
||||
+ attr.type = PERF_TYPE_SOFTWARE;
|
||||
+ attr.config = PERF_COUNT_SW_CPU_CLOCK;
|
||||
+ attr.sample_period = 1000000;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ attr.type = PERF_TYPE_HARDWARE;
|
||||
+ attr.config = PERF_COUNT_HW_CPU_CYCLES;
|
||||
+ attr.sample_period = 1200000;
|
||||
+ }
|
||||
+
|
||||
+ options = _sysprof_perf_event_attr_to_variant (&attr);
|
||||
+ promise = dex_promise_new ();
|
||||
+
|
||||
+ g_dbus_connection_call_with_unix_fd_list (connection,
|
||||
+ "org.gnome.Sysprof3",
|
||||
+ "/org/gnome/Sysprof3",
|
||||
+ "org.gnome.Sysprof3.Service",
|
||||
+ "PerfEventOpen",
|
||||
+ g_variant_new ("(@a{sv}iiht)",
|
||||
+ options,
|
||||
+ -1,
|
||||
+ cpu,
|
||||
+ -1,
|
||||
+ 0),
|
||||
+ G_VARIANT_TYPE ("(h)"),
|
||||
+ G_DBUS_CALL_FLAGS_NONE,
|
||||
+ G_MAXUINT,
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+ _perf_event_open_cb,
|
||||
+ dex_ref (promise));
|
||||
+
|
||||
+ if (-1 == (perf_fd = dex_await_fd (dex_ref (promise), error)))
|
||||
+ {
|
||||
+ g_clear_pointer (&options, g_variant_unref);
|
||||
+
|
||||
+ if (with_mmap2)
|
||||
+ {
|
||||
+ with_mmap2 = FALSE;
|
||||
+ goto try_again;
|
||||
+ }
|
||||
+
|
||||
+ if (use_software == FALSE)
|
||||
+ {
|
||||
+ with_mmap2 = TRUE;
|
||||
+ use_software = TRUE;
|
||||
+ goto try_again;
|
||||
+ }
|
||||
+
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ return g_steal_fd (&perf_fd);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+call_unwind_cb (GObject *object,
|
||||
+ GAsyncResult *result,
|
||||
+ gpointer user_data)
|
||||
+{
|
||||
+ g_autoptr(DexPromise) promise = user_data;
|
||||
+ g_autoptr(GUnixFDList) out_fd_list = NULL;
|
||||
+ g_autoptr(GVariant) out_capture_fd = NULL;
|
||||
+ g_autofd int capture_fd = -1;
|
||||
+ GError *error = NULL;
|
||||
+
|
||||
+ g_assert (IPC_IS_UNWINDER (object));
|
||||
+ g_assert (G_IS_ASYNC_RESULT (result));
|
||||
+ g_assert (DEX_IS_PROMISE (promise));
|
||||
+
|
||||
+ if (ipc_unwinder_call_unwind_finish (IPC_UNWINDER (object), &out_capture_fd, &out_fd_list, result, &error) &&
|
||||
+ -1 != (capture_fd = g_unix_fd_list_get (out_fd_list, g_variant_get_handle (out_capture_fd), &error)))
|
||||
+ dex_promise_resolve_fd (promise, g_steal_fd (&capture_fd));
|
||||
+ else
|
||||
+ dex_promise_reject (promise, error);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+create_unwinder_cb (GObject *object,
|
||||
+ GAsyncResult *result,
|
||||
+ gpointer user_data)
|
||||
+{
|
||||
+ g_autoptr(DexPromise) promise = user_data;
|
||||
+ IpcUnwinder *unwinder;
|
||||
+ GError *error = NULL;
|
||||
+
|
||||
+ if ((unwinder = ipc_unwinder_proxy_new_finish (result, &error)))
|
||||
+ dex_promise_resolve_object (promise, unwinder);
|
||||
+ else
|
||||
+ dex_promise_reject (promise, error);
|
||||
+}
|
||||
+
|
||||
+static IpcUnwinder *
|
||||
+create_unwinder (GDBusConnection *connection,
|
||||
+ GError **error)
|
||||
+{
|
||||
+ g_autoptr(DexPromise) promise = dex_promise_new ();
|
||||
+ ipc_unwinder_proxy_new (connection, G_DBUS_PROXY_FLAGS_NONE,
|
||||
+ "org.gnome.Sysprof3",
|
||||
+ "/org/gnome/Sysprof3/Unwinder",
|
||||
+ NULL,
|
||||
+ create_unwinder_cb,
|
||||
+ dex_ref (promise));
|
||||
+ return dex_await_object (dex_ref (promise), error);
|
||||
+}
|
||||
+
|
||||
+static DexFuture *
|
||||
+sysprof_user_sampler_prepare_fiber (gpointer user_data)
|
||||
+{
|
||||
+ Prepare *prepare = user_data;
|
||||
+ g_autoptr(GDBusConnection) connection = NULL;
|
||||
+ g_autoptr(GUnixFDList) fd_list = NULL;
|
||||
+ g_autoptr(GError) error = NULL;
|
||||
+ GVariantBuilder builder;
|
||||
+ gboolean all_failed = TRUE;
|
||||
+ guint n_cpu;
|
||||
+
|
||||
+ g_assert (prepare != NULL);
|
||||
+ g_assert (SYSPROF_IS_RECORDING (prepare->recording));
|
||||
+ g_assert (SYSPROF_IS_USER_SAMPLER (prepare->sampler));
|
||||
+
|
||||
+ if (!(connection = dex_await_object (dex_bus_get (G_BUS_TYPE_SYSTEM), &error)))
|
||||
+ return dex_future_new_for_error (g_steal_pointer (&error));
|
||||
+
|
||||
+ if (!dex_await (_sysprof_recording_add_file (prepare->recording,
|
||||
+ "/proc/kallsyms",
|
||||
+ TRUE),
|
||||
+ &error))
|
||||
+ {
|
||||
+ _sysprof_recording_diagnostic (prepare->recording,
|
||||
+ "Sampler",
|
||||
+ "Failed to record copy of “kallsyms” to capture: %s",
|
||||
+ error->message);
|
||||
+ g_clear_error (&error);
|
||||
+ }
|
||||
+
|
||||
+ n_cpu = g_get_num_processors ();
|
||||
+ fd_list = g_unix_fd_list_new ();
|
||||
+
|
||||
+ g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(hi)"));
|
||||
+
|
||||
+ for (guint i = 0; i < n_cpu; i++)
|
||||
+ {
|
||||
+ g_autofd int fd = _perf_event_open (connection, i, prepare->stack_size, &error);
|
||||
+
|
||||
+ if (fd == -1)
|
||||
+ {
|
||||
+ _sysprof_recording_diagnostic (prepare->recording,
|
||||
+ "Sampler",
|
||||
+ "Failed to load Perf event stream for CPU %d with stack size %u: %s",
|
||||
+ i, prepare->stack_size, error->message);
|
||||
+ g_clear_error (&error);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ int handle = g_unix_fd_list_append (fd_list, fd, &error);
|
||||
+
|
||||
+ if (handle == -1)
|
||||
+ {
|
||||
+ _sysprof_recording_diagnostic (prepare->recording,
|
||||
+ "Sampler",
|
||||
+ "Out of FDs to add to FDList: %s",
|
||||
+ error->message);
|
||||
+ g_clear_error (&error);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ g_array_append_val (prepare->sampler->perf_fds, fd);
|
||||
+ fd = -1;
|
||||
+
|
||||
+ g_variant_builder_add (&builder, "(hi)", handle, i);
|
||||
+
|
||||
+ all_failed = FALSE;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (!all_failed)
|
||||
+ {
|
||||
+ g_autoptr(IpcUnwinder) unwinder = create_unwinder (connection, &error);
|
||||
+
|
||||
+ if (unwinder == NULL)
|
||||
+ {
|
||||
+ _sysprof_recording_diagnostic (prepare->recording,
|
||||
+ "Sampler",
|
||||
+ "Failed to locate unwinder service: %s",
|
||||
+ error->message);
|
||||
+ g_clear_error (&error);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ g_autoptr(DexPromise) promise = dex_promise_new ();
|
||||
+ int event_fd_handle = g_unix_fd_list_append (fd_list, prepare->sampler->event_fd, NULL);
|
||||
+ g_autofd int fd = -1;
|
||||
+
|
||||
+ ipc_unwinder_call_unwind (unwinder,
|
||||
+ prepare->stack_size,
|
||||
+ g_variant_builder_end (&builder),
|
||||
+ g_variant_new_handle (event_fd_handle),
|
||||
+ fd_list,
|
||||
+ NULL,
|
||||
+ call_unwind_cb,
|
||||
+ dex_ref (promise));
|
||||
+
|
||||
+ fd = dex_await_fd (dex_ref (promise), &error);
|
||||
+
|
||||
+ if (fd == -1)
|
||||
+ {
|
||||
+ _sysprof_recording_diagnostic (prepare->recording,
|
||||
+ "Sampler",
|
||||
+ "Failed to setup user-space unwinder: %s",
|
||||
+ error->message);
|
||||
+ g_clear_error (&error);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ prepare->sampler->capture_fd = g_steal_fd (&fd);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ g_variant_builder_clear (&builder);
|
||||
+
|
||||
+ return dex_future_new_for_boolean (TRUE);
|
||||
+}
|
||||
+
|
||||
+static DexFuture *
|
||||
+sysprof_user_sampler_prepare (SysprofInstrument *instrument,
|
||||
+ SysprofRecording *recording)
|
||||
+{
|
||||
+ SysprofUserSampler *self = (SysprofUserSampler *)instrument;
|
||||
+ Prepare *prepare;
|
||||
+
|
||||
+ g_assert (SYSPROF_IS_INSTRUMENT (instrument));
|
||||
+ g_assert (SYSPROF_IS_RECORDING (recording));
|
||||
+
|
||||
+ prepare = g_new0 (Prepare, 1);
|
||||
+ prepare->recording = g_object_ref (recording);
|
||||
+ prepare->sampler = g_object_ref (self);
|
||||
+ prepare->stack_size = self->stack_size;
|
||||
+
|
||||
+ return dex_scheduler_spawn (NULL, 0,
|
||||
+ sysprof_user_sampler_prepare_fiber,
|
||||
+ prepare,
|
||||
+ (GDestroyNotify)prepare_free);
|
||||
+}
|
||||
+
|
||||
+typedef struct _Record
|
||||
+{
|
||||
+ SysprofRecording *recording;
|
||||
+ SysprofUserSampler *sampler;
|
||||
+ DexFuture *cancellable;
|
||||
+} Record;
|
||||
+
|
||||
+static void
|
||||
+record_free (Record *record)
|
||||
+{
|
||||
+ g_clear_object (&record->recording);
|
||||
+ g_clear_object (&record->sampler);
|
||||
+ dex_clear (&record->cancellable);
|
||||
+ g_free (record);
|
||||
+}
|
||||
+
|
||||
+static DexFuture *
|
||||
+sysprof_user_sampler_record_fiber (gpointer user_data)
|
||||
+{
|
||||
+ SysprofCaptureWriter *writer;
|
||||
+ Record *record = user_data;
|
||||
+ g_autoptr(GError) error = NULL;
|
||||
+ g_autoptr(GSource) muxer_source = NULL;
|
||||
+ guint64 exiting = 1234;
|
||||
+
|
||||
+ g_assert (record != NULL);
|
||||
+ g_assert (SYSPROF_IS_USER_SAMPLER (record->sampler));
|
||||
+ g_assert (SYSPROF_IS_RECORDING (record->recording));
|
||||
+ g_assert (DEX_IS_FUTURE (record->cancellable));
|
||||
+
|
||||
+ writer = _sysprof_recording_writer (record->recording);
|
||||
+
|
||||
+ sysprof_user_sampler_ioctl (record->sampler, TRUE);
|
||||
+
|
||||
+ g_debug ("Staring muxer for capture_fd");
|
||||
+ muxer_source = sysprof_muxer_source_new (g_steal_fd (&record->sampler->capture_fd), writer);
|
||||
+ g_source_set_static_name (muxer_source, "[stack-muxer]");
|
||||
+ g_source_attach (muxer_source, NULL);
|
||||
+
|
||||
+ if (!dex_await (dex_ref (record->cancellable), &error))
|
||||
+ g_debug ("UserSampler shutting down for reason: %s", error->message);
|
||||
+
|
||||
+ write (record->sampler->event_fd, &exiting, sizeof exiting);
|
||||
+
|
||||
+ g_source_destroy (muxer_source);
|
||||
+
|
||||
+ sysprof_user_sampler_ioctl (record->sampler, FALSE);
|
||||
+
|
||||
+ return dex_future_new_for_boolean (TRUE);
|
||||
+}
|
||||
+
|
||||
+static DexFuture *
|
||||
+sysprof_user_sampler_record (SysprofInstrument *instrument,
|
||||
+ SysprofRecording *recording,
|
||||
+ GCancellable *cancellable)
|
||||
+{
|
||||
+ SysprofUserSampler *self = (SysprofUserSampler *)instrument;
|
||||
+ Record *record;
|
||||
+
|
||||
+ g_assert (SYSPROF_IS_INSTRUMENT (instrument));
|
||||
+ g_assert (SYSPROF_IS_RECORDING (recording));
|
||||
+ g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
|
||||
+
|
||||
+ record = g_new0 (Record, 1);
|
||||
+ record->recording = g_object_ref (recording);
|
||||
+ record->sampler = g_object_ref (self);
|
||||
+ record->cancellable = dex_cancellable_new_from_cancellable (cancellable);
|
||||
+
|
||||
+ return dex_scheduler_spawn (NULL, 0,
|
||||
+ sysprof_user_sampler_record_fiber,
|
||||
+ record,
|
||||
+ (GDestroyNotify)record_free);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+sysprof_user_sampler_finalize (GObject *object)
|
||||
+{
|
||||
+ SysprofUserSampler *self = (SysprofUserSampler *)object;
|
||||
+
|
||||
+ g_clear_pointer (&self->perf_fds, g_array_unref);
|
||||
+
|
||||
+ g_clear_fd (&self->capture_fd, NULL);
|
||||
+ g_clear_fd (&self->event_fd, NULL);
|
||||
+
|
||||
+ G_OBJECT_CLASS (sysprof_user_sampler_parent_class)->finalize (object);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+sysprof_user_sampler_class_init (SysprofUserSamplerClass *klass)
|
||||
+{
|
||||
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
+ SysprofInstrumentClass *instrument_class = SYSPROF_INSTRUMENT_CLASS (klass);
|
||||
+
|
||||
+ object_class->finalize = sysprof_user_sampler_finalize;
|
||||
+
|
||||
+ instrument_class->list_required_policy = sysprof_user_sampler_list_required_policy;
|
||||
+ instrument_class->prepare = sysprof_user_sampler_prepare;
|
||||
+ instrument_class->record = sysprof_user_sampler_record;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+sysprof_user_sampler_init (SysprofUserSampler *self)
|
||||
+{
|
||||
+ self->capture_fd = -1;
|
||||
+ self->event_fd = eventfd (0, EFD_CLOEXEC);
|
||||
+
|
||||
+ self->perf_fds = g_array_new (FALSE, FALSE, sizeof (int));
|
||||
+ g_array_set_clear_func (self->perf_fds, close_fd);
|
||||
+}
|
||||
+
|
||||
+SysprofInstrument *
|
||||
+sysprof_user_sampler_new (guint stack_size)
|
||||
+{
|
||||
+ SysprofUserSampler *self;
|
||||
+
|
||||
+ g_return_val_if_fail (stack_size > 0, NULL);
|
||||
+ g_return_val_if_fail (stack_size % sysprof_getpagesize () == 0, NULL);
|
||||
+
|
||||
+ self = g_object_new (SYSPROF_TYPE_USER_SAMPLER, NULL);
|
||||
+ self->stack_size = stack_size;
|
||||
+
|
||||
+ return SYSPROF_INSTRUMENT (self);
|
||||
+}
|
||||
diff --git a/src/libsysprof/sysprof-user-sampler.h b/src/libsysprof/sysprof-user-sampler.h
|
||||
new file mode 100644
|
||||
index 00000000..d39e6095
|
||||
--- /dev/null
|
||||
+++ b/src/libsysprof/sysprof-user-sampler.h
|
||||
@@ -0,0 +1,43 @@
|
||||
+/*
|
||||
+ * sysprof-user-sampler.h
|
||||
+ *
|
||||
+ * Copyright 2024 Christian Hergert <chergert@redhat.com>
|
||||
+ *
|
||||
+ * This program is free software: you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License as published by
|
||||
+ * the Free Software Foundation, either version 3 of the License, or
|
||||
+ * (at your option) any later version.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License
|
||||
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
+ *
|
||||
+ * SPDX-License-Identifier: GPL-3.0-or-later
|
||||
+ */
|
||||
+
|
||||
+#pragma once
|
||||
+
|
||||
+#include "sysprof-instrument.h"
|
||||
+
|
||||
+G_BEGIN_DECLS
|
||||
+
|
||||
+#define SYSPROF_TYPE_USER_SAMPLER (sysprof_user_sampler_get_type())
|
||||
+#define SYSPROF_IS_USER_SAMPLER(obj) G_TYPE_CHECK_INSTANCE_TYPE(obj, SYSPROF_TYPE_USER_SAMPLER)
|
||||
+#define SYSPROF_USER_SAMPLER(obj) G_TYPE_CHECK_INSTANCE_CAST(obj, SYSPROF_TYPE_USER_SAMPLER, SysprofUserSampler)
|
||||
+#define SYSPROF_USER_SAMPLER_CLASS(klass) G_TYPE_CHECK_CLASS_CAST(klass, SYSPROF_TYPE_USER_SAMPLER, SysprofUserSamplerClass)
|
||||
+
|
||||
+typedef struct _SysprofUserSampler SysprofUserSampler;
|
||||
+typedef struct _SysprofUserSamplerClass SysprofUserSamplerClass;
|
||||
+
|
||||
+SYSPROF_AVAILABLE_IN_47
|
||||
+GType sysprof_user_sampler_get_type (void) G_GNUC_CONST;
|
||||
+SYSPROF_AVAILABLE_IN_47
|
||||
+SysprofInstrument *sysprof_user_sampler_new (guint stack_size);
|
||||
+
|
||||
+G_DEFINE_AUTOPTR_CLEANUP_FUNC (SysprofUserSampler, g_object_unref)
|
||||
+
|
||||
+G_END_DECLS
|
||||
diff --git a/src/libsysprof/sysprof.h b/src/libsysprof/sysprof.h
|
||||
index d30f9fd4..514e332b 100644
|
||||
--- a/src/libsysprof/sysprof.h
|
||||
+++ b/src/libsysprof/sysprof.h
|
||||
@@ -89,6 +89,7 @@ G_BEGIN_DECLS
|
||||
# include "sysprof-time-span.h"
|
||||
# include "sysprof-tracefd-consumer.h"
|
||||
# include "sysprof-tracer.h"
|
||||
+# include "sysprof-user-sampler.h"
|
||||
#undef SYSPROF_INSIDE
|
||||
|
||||
G_END_DECLS
|
||||
--
|
||||
2.45.2
|
||||
|
60
0018-sysprof-cli-add-support-for-live-unwinding.patch
Normal file
60
0018-sysprof-cli-add-support-for-live-unwinding.patch
Normal file
@ -0,0 +1,60 @@
|
||||
From f7118874cfac04b8febf38ee9b073b6d46cc3f08 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Hergert <chergert@redhat.com>
|
||||
Date: Sun, 3 Nov 2024 10:54:57 -0800
|
||||
Subject: [PATCH 18/31] sysprof-cli: add support for live unwinding
|
||||
|
||||
This allows you to specify --stack-size=(multiple_of_page_size) to unwind
|
||||
from captured stack contents. It will use the new SysprofUserSampler to
|
||||
unwind stack traces via sysprof-live-unwinder.
|
||||
---
|
||||
src/sysprof-cli/sysprof-cli.c | 13 ++++++++++++-
|
||||
1 file changed, 12 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/sysprof-cli/sysprof-cli.c b/src/sysprof-cli/sysprof-cli.c
|
||||
index e00bd6b1..1c9ce928 100644
|
||||
--- a/src/sysprof-cli/sysprof-cli.c
|
||||
+++ b/src/sysprof-cli/sysprof-cli.c
|
||||
@@ -303,6 +303,7 @@ main (int argc,
|
||||
gboolean scheduler_details = FALSE;
|
||||
gboolean system_bus = FALSE;
|
||||
gboolean session_bus = FALSE;
|
||||
+ int stack_size = 0;
|
||||
int pid = -1;
|
||||
int fd;
|
||||
int flags;
|
||||
@@ -335,6 +336,7 @@ main (int argc,
|
||||
{ "version", 0, 0, G_OPTION_ARG_NONE, &version, N_("Print the sysprof-cli version and exit") },
|
||||
{ "buffer-size", 0, 0, G_OPTION_ARG_INT, &n_buffer_pages, N_("The size of the buffer in pages (1 = 1 page)") },
|
||||
{ "monitor-bus", 0, 0, G_OPTION_ARG_STRING_ARRAY, &monitor_bus, N_("Additional D-Bus address to monitor") },
|
||||
+ { "stack-size", 0, 0, G_OPTION_ARG_INT, &stack_size, N_("Stack size to copy for unwinding in user-space") },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
@@ -379,6 +381,10 @@ Examples:\n\
|
||||
\n\
|
||||
# Merge multiple syscap files into one\n\
|
||||
sysprof-cli --merge a.syscap b.syscap > c.syscap\n\
|
||||
+\n\
|
||||
+ # Unwind by capturing stack/register contents instead of frame-pointers\n\
|
||||
+ # where the stack-size is a multiple of page-size\n\
|
||||
+ sysprof-cli --stack-size=8192\n\
|
||||
"));
|
||||
|
||||
if (!g_option_context_parse (context, &argc, &argv, &error))
|
||||
@@ -533,7 +539,12 @@ Examples:\n\
|
||||
sysprof_profiler_add_instrument (profiler, sysprof_system_logs_new ());
|
||||
|
||||
if (!no_perf)
|
||||
- sysprof_profiler_add_instrument (profiler, sysprof_sampler_new ());
|
||||
+ {
|
||||
+ if (stack_size == 0)
|
||||
+ sysprof_profiler_add_instrument (profiler, sysprof_sampler_new ());
|
||||
+ else
|
||||
+ sysprof_profiler_add_instrument (profiler, sysprof_user_sampler_new (stack_size));
|
||||
+ }
|
||||
|
||||
if (!no_disk)
|
||||
sysprof_profiler_add_instrument (profiler, sysprof_disk_usage_new ());
|
||||
--
|
||||
2.45.2
|
||||
|
506
0019-sysprof-add-UI-for-live-unwinding.patch
Normal file
506
0019-sysprof-add-UI-for-live-unwinding.patch
Normal file
@ -0,0 +1,506 @@
|
||||
From f02e19820e5a3b223f2b563946daa80693c98ca2 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Hergert <chergert@redhat.com>
|
||||
Date: Sun, 3 Nov 2024 10:57:58 -0800
|
||||
Subject: [PATCH 19/31] sysprof: add UI for live unwinding
|
||||
|
||||
This adds UI to specify the amount of stack contents to copy along with
|
||||
the CPU registers so that you may unwind in user-space.
|
||||
---
|
||||
src/sysprof/meson.build | 1 +
|
||||
src/sysprof/sysprof-greeter.c | 32 +++++
|
||||
src/sysprof/sysprof-greeter.ui | 67 +++++++++++
|
||||
src/sysprof/sysprof-recording-template.c | 41 ++++++-
|
||||
src/sysprof/sysprof-stack-size.c | 141 +++++++++++++++++++++++
|
||||
src/sysprof/sysprof-stack-size.h | 35 ++++++
|
||||
6 files changed, 316 insertions(+), 1 deletion(-)
|
||||
create mode 100644 src/sysprof/sysprof-stack-size.c
|
||||
create mode 100644 src/sysprof/sysprof-stack-size.h
|
||||
|
||||
diff --git a/src/sysprof/meson.build b/src/sysprof/meson.build
|
||||
index ca42ead3..ab6a701a 100644
|
||||
--- a/src/sysprof/meson.build
|
||||
+++ b/src/sysprof/meson.build
|
||||
@@ -57,6 +57,7 @@ sysprof_sources = [
|
||||
'sysprof-sidebar.c',
|
||||
'sysprof-single-model.c',
|
||||
'sysprof-split-layer.c',
|
||||
+ 'sysprof-stack-size.c',
|
||||
'sysprof-storage-section.c',
|
||||
'sysprof-symbol-label.c',
|
||||
'sysprof-task-row.c',
|
||||
diff --git a/src/sysprof/sysprof-greeter.c b/src/sysprof/sysprof-greeter.c
|
||||
index 72f4dd5d..52eff370 100644
|
||||
--- a/src/sysprof/sysprof-greeter.c
|
||||
+++ b/src/sysprof/sysprof-greeter.c
|
||||
@@ -31,6 +31,7 @@
|
||||
#include "sysprof-power-profiles.h"
|
||||
#include "sysprof-recording-pad.h"
|
||||
#include "sysprof-recording-template.h"
|
||||
+#include "sysprof-stack-size.h"
|
||||
#include "sysprof-window.h"
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (SysprofCaptureWriter, sysprof_capture_writer_unref)
|
||||
@@ -56,6 +57,7 @@ struct _SysprofGreeter
|
||||
GtkSwitch *bundle_symbols;
|
||||
GtkButton *record_to_memory;
|
||||
AdwComboRow *power_combo;
|
||||
+ AdwComboRow *sample_user_stack_size;
|
||||
SysprofRecordingTemplate *recording_template;
|
||||
};
|
||||
|
||||
@@ -455,6 +457,26 @@ translate_power_profile (GtkStringObject *strobj)
|
||||
return g_strdup (str);
|
||||
}
|
||||
|
||||
+static void
|
||||
+on_stack_size_changed_cb (SysprofGreeter *self,
|
||||
+ GParamSpec *pspec,
|
||||
+ AdwComboRow *row)
|
||||
+{
|
||||
+ GObject *item;
|
||||
+
|
||||
+ g_assert (SYSPROF_IS_GREETER (self));
|
||||
+ g_assert (ADW_IS_COMBO_ROW (row));
|
||||
+
|
||||
+ if ((item = adw_combo_row_get_selected_item (row)))
|
||||
+ {
|
||||
+ guint stack_size = sysprof_stack_size_get_size (SYSPROF_STACK_SIZE (item));
|
||||
+
|
||||
+ g_object_set (self->recording_template,
|
||||
+ "stack-size", stack_size,
|
||||
+ NULL);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static void
|
||||
sysprof_greeter_dispose (GObject *object)
|
||||
{
|
||||
@@ -492,6 +514,7 @@ sysprof_greeter_class_init (SysprofGreeterClass *klass)
|
||||
gtk_widget_class_bind_template_child (widget_class, SysprofGreeter, recording_template);
|
||||
gtk_widget_class_bind_template_child (widget_class, SysprofGreeter, sample_javascript_stacks);
|
||||
gtk_widget_class_bind_template_child (widget_class, SysprofGreeter, sample_native_stacks);
|
||||
+ gtk_widget_class_bind_template_child (widget_class, SysprofGreeter, sample_user_stack_size);
|
||||
gtk_widget_class_bind_template_child (widget_class, SysprofGreeter, sidebar_list_box);
|
||||
gtk_widget_class_bind_template_child (widget_class, SysprofGreeter, view_stack);
|
||||
|
||||
@@ -507,6 +530,7 @@ sysprof_greeter_class_init (SysprofGreeterClass *klass)
|
||||
|
||||
g_type_ensure (SYSPROF_TYPE_ENTRY_POPOVER);
|
||||
g_type_ensure (SYSPROF_TYPE_RECORDING_TEMPLATE);
|
||||
+ g_type_ensure (SYSPROF_TYPE_STACK_SIZE);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -540,6 +564,14 @@ sysprof_greeter_init (SysprofGreeter *self)
|
||||
gtk_list_box_select_row (self->sidebar_list_box, row);
|
||||
sidebar_row_activated_cb (self, row, self->sidebar_list_box);
|
||||
|
||||
+ g_signal_connect_object (self->sample_user_stack_size,
|
||||
+ "notify::selected-item",
|
||||
+ G_CALLBACK (on_stack_size_changed_cb),
|
||||
+ self,
|
||||
+ G_CONNECT_SWAPPED);
|
||||
+ /* Set to 16KB */
|
||||
+ adw_combo_row_set_selected (self->sample_user_stack_size, 1);
|
||||
+
|
||||
gtk_widget_grab_focus (GTK_WIDGET (self->record_to_memory));
|
||||
}
|
||||
|
||||
diff --git a/src/sysprof/sysprof-greeter.ui b/src/sysprof/sysprof-greeter.ui
|
||||
index 35e790f5..f7ebbc29 100644
|
||||
--- a/src/sysprof/sysprof-greeter.ui
|
||||
+++ b/src/sysprof/sysprof-greeter.ui
|
||||
@@ -106,6 +106,41 @@
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
+ <child>
|
||||
+ <object class="AdwExpanderRow">
|
||||
+ <property name="title" translatable="yes">Unwind Stacks in User Space</property>
|
||||
+ <property name="subtitle" translatable="yes">Copy stack contents and registers for unwinding in user-space</property>
|
||||
+ <property name="expanded" bind-source="sample_user_stack" bind-property="active" bind-flags="sync-create|bidirectional"/>
|
||||
+ <child type="action">
|
||||
+ <object class="GtkSwitch" id="sample_user_stack">
|
||||
+ <property name="halign">end</property>
|
||||
+ <property name="valign">center</property>
|
||||
+ <property name="active" bind-source="recording_template" bind-flags="bidirectional|sync-create" bind-property="user-stacks"/>
|
||||
+ </object>
|
||||
+ </child>
|
||||
+ <child>
|
||||
+ <object class="AdwComboRow" id="sample_user_stack_size">
|
||||
+ <property name="title" translatable="yes">Stack Size</property>
|
||||
+ <property name="subtitle" translatable="yes">The number of bytes to copy from the stack</property>
|
||||
+ <property name="model">stack_sizes</property>
|
||||
+ <property name="expression">
|
||||
+ <lookup name="label" type="SysprofStackSize"/>
|
||||
+ </property>
|
||||
+ </object>
|
||||
+ </child>
|
||||
+ </object>
|
||||
+ </child>
|
||||
+ <child>
|
||||
+ <object class="GtkLabel">
|
||||
+ <property name="label" translatable="yes">Unwinding in user-space has considerable overhead but may help in situations where frame-pointers are unavailable.</property>
|
||||
+ <property name="xalign">0</property>
|
||||
+ <property name="margin-top">8</property>
|
||||
+ <style>
|
||||
+ <class name="caption"/>
|
||||
+ <class name="dim-label"/>
|
||||
+ </style>
|
||||
+ </object>
|
||||
+ </child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@@ -664,4 +699,36 @@
|
||||
</object>
|
||||
<object class="GtkStringList" id="envvars">
|
||||
</object>
|
||||
+ <object class="GListStore" id="stack_sizes">
|
||||
+ <child>
|
||||
+ <object class="SysprofStackSize">
|
||||
+ <property name="label">8 KB</property>
|
||||
+ <property name="size">8192</property>
|
||||
+ </object>
|
||||
+ </child>
|
||||
+ <child>
|
||||
+ <object class="SysprofStackSize">
|
||||
+ <property name="label">16 KB</property>
|
||||
+ <property name="size">16384</property>
|
||||
+ </object>
|
||||
+ </child>
|
||||
+ <child>
|
||||
+ <object class="SysprofStackSize">
|
||||
+ <property name="label">24 KB</property>
|
||||
+ <property name="size">24576</property>
|
||||
+ </object>
|
||||
+ </child>
|
||||
+ <child>
|
||||
+ <object class="SysprofStackSize">
|
||||
+ <property name="label">32 KB</property>
|
||||
+ <property name="size">32768</property>
|
||||
+ </object>
|
||||
+ </child>
|
||||
+ <child>
|
||||
+ <object class="SysprofStackSize">
|
||||
+ <property name="label">64 KB</property>
|
||||
+ <property name="size">65536</property>
|
||||
+ </object>
|
||||
+ </child>
|
||||
+ </object>
|
||||
</interface>
|
||||
diff --git a/src/sysprof/sysprof-recording-template.c b/src/sysprof/sysprof-recording-template.c
|
||||
index 50f6c957..ee4d4f01 100644
|
||||
--- a/src/sysprof/sysprof-recording-template.c
|
||||
+++ b/src/sysprof/sysprof-recording-template.c
|
||||
@@ -22,6 +22,8 @@
|
||||
|
||||
#include "sysprof-recording-template.h"
|
||||
|
||||
+#define DEFAULT_STACK_SIZE (4096*4)
|
||||
+
|
||||
struct _SysprofRecordingTemplate
|
||||
{
|
||||
GObject parent_instance;
|
||||
@@ -31,6 +33,8 @@ struct _SysprofRecordingTemplate
|
||||
char *power_profile;
|
||||
char **environ;
|
||||
|
||||
+ guint stack_size;
|
||||
+
|
||||
guint battery_charge : 1;
|
||||
guint bundle_symbols : 1;
|
||||
guint clear_environ : 1;
|
||||
@@ -49,6 +53,7 @@ struct _SysprofRecordingTemplate
|
||||
guint session_bus : 1;
|
||||
guint system_bus : 1;
|
||||
guint system_log : 1;
|
||||
+ guint user_stacks : 1;
|
||||
};
|
||||
|
||||
enum {
|
||||
@@ -73,8 +78,10 @@ enum {
|
||||
PROP_POWER_PROFILE,
|
||||
PROP_SCHEDULER_DETAILS,
|
||||
PROP_SESSION_BUS,
|
||||
+ PROP_STACK_SIZE,
|
||||
PROP_SYSTEM_BUS,
|
||||
PROP_SYSTEM_LOG,
|
||||
+ PROP_USER_STACKS,
|
||||
N_PROPS
|
||||
};
|
||||
|
||||
@@ -185,6 +192,10 @@ sysprof_recording_template_get_property (GObject *object,
|
||||
g_value_set_boolean (value, self->session_bus);
|
||||
break;
|
||||
|
||||
+ case PROP_STACK_SIZE:
|
||||
+ g_value_set_uint (value, self->stack_size);
|
||||
+ break;
|
||||
+
|
||||
case PROP_SYSTEM_BUS:
|
||||
g_value_set_boolean (value, self->system_bus);
|
||||
break;
|
||||
@@ -193,6 +204,10 @@ sysprof_recording_template_get_property (GObject *object,
|
||||
g_value_set_boolean (value, self->system_log);
|
||||
break;
|
||||
|
||||
+ case PROP_USER_STACKS:
|
||||
+ g_value_set_boolean (value, self->user_stacks);
|
||||
+ break;
|
||||
+
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
@@ -289,6 +304,10 @@ sysprof_recording_template_set_property (GObject *object,
|
||||
self->session_bus = g_value_get_boolean (value);
|
||||
break;
|
||||
|
||||
+ case PROP_STACK_SIZE:
|
||||
+ self->stack_size = g_value_get_uint (value);
|
||||
+ break;
|
||||
+
|
||||
case PROP_SYSTEM_BUS:
|
||||
self->system_bus = g_value_get_boolean (value);
|
||||
break;
|
||||
@@ -297,6 +316,10 @@ sysprof_recording_template_set_property (GObject *object,
|
||||
self->system_log = g_value_get_boolean (value);
|
||||
break;
|
||||
|
||||
+ case PROP_USER_STACKS:
|
||||
+ self->user_stacks = g_value_get_boolean (value);
|
||||
+ break;
|
||||
+
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
@@ -421,6 +444,16 @@ sysprof_recording_template_class_init (SysprofRecordingTemplateClass *klass)
|
||||
TRUE,
|
||||
(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
+ properties[PROP_USER_STACKS] =
|
||||
+ g_param_spec_boolean ("user-stacks", NULL, NULL,
|
||||
+ FALSE,
|
||||
+ (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
+
|
||||
+ properties[PROP_STACK_SIZE] =
|
||||
+ g_param_spec_uint ("stack-size", NULL, NULL,
|
||||
+ 0, G_MAXUINT, DEFAULT_STACK_SIZE,
|
||||
+ (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
+
|
||||
g_object_class_install_properties (object_class, N_PROPS, properties);
|
||||
}
|
||||
|
||||
@@ -439,6 +472,7 @@ sysprof_recording_template_init (SysprofRecordingTemplate *self)
|
||||
self->system_log = TRUE;
|
||||
self->command_line = g_strdup ("");
|
||||
self->cwd = g_strdup("");
|
||||
+ self->stack_size = DEFAULT_STACK_SIZE;
|
||||
}
|
||||
|
||||
SysprofRecordingTemplate *
|
||||
@@ -619,7 +653,12 @@ sysprof_recording_template_apply (SysprofRecordingTemplate *self,
|
||||
sysprof_profiler_add_instrument (profiler, sysprof_memory_usage_new ());
|
||||
|
||||
if (self->native_stacks)
|
||||
- sysprof_profiler_add_instrument (profiler, sysprof_sampler_new ());
|
||||
+ {
|
||||
+ if (self->user_stacks)
|
||||
+ sysprof_profiler_add_instrument (profiler, sysprof_user_sampler_new (self->stack_size));
|
||||
+ else
|
||||
+ sysprof_profiler_add_instrument (profiler, sysprof_sampler_new ());
|
||||
+ }
|
||||
|
||||
if (self->network_usage)
|
||||
sysprof_profiler_add_instrument (profiler, sysprof_network_usage_new ());
|
||||
diff --git a/src/sysprof/sysprof-stack-size.c b/src/sysprof/sysprof-stack-size.c
|
||||
new file mode 100644
|
||||
index 00000000..d6652766
|
||||
--- /dev/null
|
||||
+++ b/src/sysprof/sysprof-stack-size.c
|
||||
@@ -0,0 +1,141 @@
|
||||
+/*
|
||||
+ * sysprof-stack-size.c
|
||||
+ *
|
||||
+ * Copyright 2024 Christian Hergert <chergert@redhat.com>
|
||||
+ *
|
||||
+ * This program is free software: you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License as published by
|
||||
+ * the Free Software Foundation, either version 3 of the License, or
|
||||
+ * (at your option) any later version.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License
|
||||
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
+ *
|
||||
+ * SPDX-License-Identifier: GPL-3.0-or-later
|
||||
+ */
|
||||
+
|
||||
+#include "config.h"
|
||||
+
|
||||
+#include "sysprof-stack-size.h"
|
||||
+
|
||||
+struct _SysprofStackSize
|
||||
+{
|
||||
+ GObject parent_instance;
|
||||
+ char *label;
|
||||
+ guint size;
|
||||
+};
|
||||
+
|
||||
+enum {
|
||||
+ PROP_0,
|
||||
+ PROP_SIZE,
|
||||
+ PROP_LABEL,
|
||||
+ N_PROPS
|
||||
+};
|
||||
+
|
||||
+G_DEFINE_FINAL_TYPE (SysprofStackSize, sysprof_stack_size, G_TYPE_OBJECT)
|
||||
+
|
||||
+static GParamSpec *properties[N_PROPS];
|
||||
+
|
||||
+static void
|
||||
+sysprof_stack_size_finalize (GObject *object)
|
||||
+{
|
||||
+ SysprofStackSize *self = (SysprofStackSize *)object;
|
||||
+
|
||||
+ g_clear_pointer (&self->label, g_free);
|
||||
+
|
||||
+ G_OBJECT_CLASS (sysprof_stack_size_parent_class)->finalize (object);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+sysprof_stack_size_get_property (GObject *object,
|
||||
+ guint prop_id,
|
||||
+ GValue *value,
|
||||
+ GParamSpec *pspec)
|
||||
+{
|
||||
+ SysprofStackSize *self = SYSPROF_STACK_SIZE (object);
|
||||
+
|
||||
+ switch (prop_id)
|
||||
+ {
|
||||
+ case PROP_SIZE:
|
||||
+ g_value_set_uint (value, self->size);
|
||||
+ break;
|
||||
+
|
||||
+ case PROP_LABEL:
|
||||
+ g_value_set_string (value, self->label);
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+sysprof_stack_size_set_property (GObject *object,
|
||||
+ guint prop_id,
|
||||
+ const GValue *value,
|
||||
+ GParamSpec *pspec)
|
||||
+{
|
||||
+ SysprofStackSize *self = SYSPROF_STACK_SIZE (object);
|
||||
+
|
||||
+ switch (prop_id)
|
||||
+ {
|
||||
+ case PROP_SIZE:
|
||||
+ self->size = g_value_get_uint (value);
|
||||
+ break;
|
||||
+
|
||||
+ case PROP_LABEL:
|
||||
+ g_set_str (&self->label, g_value_get_string (value));
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+sysprof_stack_size_class_init (SysprofStackSizeClass *klass)
|
||||
+{
|
||||
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
+
|
||||
+ object_class->finalize = sysprof_stack_size_finalize;
|
||||
+ object_class->get_property = sysprof_stack_size_get_property;
|
||||
+ object_class->set_property = sysprof_stack_size_set_property;
|
||||
+
|
||||
+ properties[PROP_SIZE] =
|
||||
+ g_param_spec_uint ("size", NULL, NULL,
|
||||
+ 0, (4096*32), 0,
|
||||
+ (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
+
|
||||
+ properties[PROP_LABEL] =
|
||||
+ g_param_spec_string ("label", NULL, NULL,
|
||||
+ NULL,
|
||||
+ (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
+
|
||||
+ g_object_class_install_properties (object_class, N_PROPS, properties);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+sysprof_stack_size_init (SysprofStackSize *self)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+guint
|
||||
+sysprof_stack_size_get_size (SysprofStackSize *self)
|
||||
+{
|
||||
+ g_return_val_if_fail (SYSPROF_IS_STACK_SIZE (self), 0);
|
||||
+
|
||||
+ return self->size;
|
||||
+}
|
||||
+
|
||||
+const char *
|
||||
+sysprof_stack_size_get_label (SysprofStackSize *self)
|
||||
+{
|
||||
+ g_return_val_if_fail (SYSPROF_IS_STACK_SIZE (self), NULL);
|
||||
+
|
||||
+ return self->label;
|
||||
+}
|
||||
diff --git a/src/sysprof/sysprof-stack-size.h b/src/sysprof/sysprof-stack-size.h
|
||||
new file mode 100644
|
||||
index 00000000..5dd7f9c2
|
||||
--- /dev/null
|
||||
+++ b/src/sysprof/sysprof-stack-size.h
|
||||
@@ -0,0 +1,35 @@
|
||||
+/*
|
||||
+ * sysprof-stack-size.h
|
||||
+ *
|
||||
+ * Copyright 2024 Christian Hergert <chergert@redhat.com>
|
||||
+ *
|
||||
+ * This program is free software: you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License as published by
|
||||
+ * the Free Software Foundation, either version 3 of the License, or
|
||||
+ * (at your option) any later version.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License
|
||||
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
+ *
|
||||
+ * SPDX-License-Identifier: GPL-3.0-or-later
|
||||
+ */
|
||||
+
|
||||
+#pragma once
|
||||
+
|
||||
+#include <glib-object.h>
|
||||
+
|
||||
+G_BEGIN_DECLS
|
||||
+
|
||||
+#define SYSPROF_TYPE_STACK_SIZE (sysprof_stack_size_get_type())
|
||||
+
|
||||
+G_DECLARE_FINAL_TYPE (SysprofStackSize, sysprof_stack_size, SYSPROF, STACK_SIZE, GObject)
|
||||
+
|
||||
+guint sysprof_stack_size_get_size (SysprofStackSize *self);
|
||||
+const char *sysprof_stack_size_get_label (SysprofStackSize *self);
|
||||
+
|
||||
+G_END_DECLS
|
||||
--
|
||||
2.45.2
|
||||
|
49
0020-sysprof-live-unwinder-ifdef-unused-code-off-x86.patch
Normal file
49
0020-sysprof-live-unwinder-ifdef-unused-code-off-x86.patch
Normal file
@ -0,0 +1,49 @@
|
||||
From 51c7529c515c2e5c4362676e44f2679ce8cc66db Mon Sep 17 00:00:00 2001
|
||||
From: Christian Hergert <chergert@redhat.com>
|
||||
Date: Mon, 4 Nov 2024 14:21:15 -0800
|
||||
Subject: [PATCH 20/31] sysprof-live-unwinder: ifdef unused code off x86
|
||||
|
||||
Fixes a compiler warning about unused functions.
|
||||
---
|
||||
src/sysprof-live-unwinder/sysprof-live-process.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/src/sysprof-live-unwinder/sysprof-live-process.c b/src/sysprof-live-unwinder/sysprof-live-process.c
|
||||
index 7932048b..90fd2633 100644
|
||||
--- a/src/sysprof-live-unwinder/sysprof-live-process.c
|
||||
+++ b/src/sysprof-live-unwinder/sysprof-live-process.c
|
||||
@@ -80,6 +80,7 @@ typedef struct _SysprofUnwinder
|
||||
|
||||
static SysprofUnwinder *current_unwinder;
|
||||
|
||||
+#if defined(__x86_64__) || defined(__i386__)
|
||||
static inline GPid
|
||||
sysprof_unwinder_next_thread (Dwfl *dwfl,
|
||||
void *user_data,
|
||||
@@ -230,6 +231,7 @@ sysprof_unwinder_frame_cb (Dwfl_Frame *frame,
|
||||
|
||||
return DWARF_CB_OK;
|
||||
}
|
||||
+#endif
|
||||
|
||||
static inline guint
|
||||
sysprof_unwind (SysprofLiveProcess *self,
|
||||
@@ -406,6 +408,7 @@ sysprof_live_process_is_active (SysprofLiveProcess *self)
|
||||
return self->fd > -1;
|
||||
}
|
||||
|
||||
+#if defined(__x86_64__) || defined(__i386__)
|
||||
static Dwfl *
|
||||
sysprof_live_process_get_dwfl (SysprofLiveProcess *self)
|
||||
{
|
||||
@@ -440,6 +443,7 @@ sysprof_live_process_get_dwfl (SysprofLiveProcess *self)
|
||||
|
||||
return self->dwfl;
|
||||
}
|
||||
+#endif
|
||||
|
||||
guint
|
||||
sysprof_live_process_unwind (SysprofLiveProcess *self,
|
||||
--
|
||||
2.45.2
|
||||
|
58
0021-sysprof-only-show-user-stack-sampling-on-x86.patch
Normal file
58
0021-sysprof-only-show-user-stack-sampling-on-x86.patch
Normal file
@ -0,0 +1,58 @@
|
||||
From 7ae54a2e334dead967216f17455026fbcf256186 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Hergert <chergert@redhat.com>
|
||||
Date: Mon, 4 Nov 2024 14:25:07 -0800
|
||||
Subject: [PATCH 21/31] sysprof: only show user stack sampling on x86
|
||||
|
||||
That is the only place it works currently (and is necessary).
|
||||
---
|
||||
src/sysprof/sysprof-greeter.c | 6 ++++++
|
||||
src/sysprof/sysprof-greeter.ui | 2 +-
|
||||
2 files changed, 7 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/sysprof/sysprof-greeter.c b/src/sysprof/sysprof-greeter.c
|
||||
index 52eff370..e0313e81 100644
|
||||
--- a/src/sysprof/sysprof-greeter.c
|
||||
+++ b/src/sysprof/sysprof-greeter.c
|
||||
@@ -58,6 +58,7 @@ struct _SysprofGreeter
|
||||
GtkButton *record_to_memory;
|
||||
AdwComboRow *power_combo;
|
||||
AdwComboRow *sample_user_stack_size;
|
||||
+ AdwExpanderRow *user_stacks;
|
||||
SysprofRecordingTemplate *recording_template;
|
||||
};
|
||||
|
||||
@@ -516,6 +517,7 @@ sysprof_greeter_class_init (SysprofGreeterClass *klass)
|
||||
gtk_widget_class_bind_template_child (widget_class, SysprofGreeter, sample_native_stacks);
|
||||
gtk_widget_class_bind_template_child (widget_class, SysprofGreeter, sample_user_stack_size);
|
||||
gtk_widget_class_bind_template_child (widget_class, SysprofGreeter, sidebar_list_box);
|
||||
+ gtk_widget_class_bind_template_child (widget_class, SysprofGreeter, user_stacks);
|
||||
gtk_widget_class_bind_template_child (widget_class, SysprofGreeter, view_stack);
|
||||
|
||||
gtk_widget_class_bind_template_callback (widget_class, sidebar_row_activated_cb);
|
||||
@@ -572,6 +574,10 @@ sysprof_greeter_init (SysprofGreeter *self)
|
||||
/* Set to 16KB */
|
||||
adw_combo_row_set_selected (self->sample_user_stack_size, 1);
|
||||
|
||||
+#if !defined(__x86_64__) && !defined(__i386__)
|
||||
+ gtk_widget_set_visible (GTK_WIDGET (self->user_stacks), FALSE);
|
||||
+#endif
|
||||
+
|
||||
gtk_widget_grab_focus (GTK_WIDGET (self->record_to_memory));
|
||||
}
|
||||
|
||||
diff --git a/src/sysprof/sysprof-greeter.ui b/src/sysprof/sysprof-greeter.ui
|
||||
index f7ebbc29..92ade34d 100644
|
||||
--- a/src/sysprof/sysprof-greeter.ui
|
||||
+++ b/src/sysprof/sysprof-greeter.ui
|
||||
@@ -107,7 +107,7 @@
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
- <object class="AdwExpanderRow">
|
||||
+ <object class="AdwExpanderRow" id="user_stacks">
|
||||
<property name="title" translatable="yes">Unwind Stacks in User Space</property>
|
||||
<property name="subtitle" translatable="yes">Copy stack contents and registers for unwinding in user-space</property>
|
||||
<property name="expanded" bind-source="sample_user_stack" bind-property="active" bind-flags="sync-create|bidirectional"/>
|
||||
--
|
||||
2.45.2
|
||||
|
@ -0,0 +1,30 @@
|
||||
From be843d84b49f7cd7ce15352ab187e4197cdd887e Mon Sep 17 00:00:00 2001
|
||||
From: Christian Hergert <chergert@redhat.com>
|
||||
Date: Fri, 8 Nov 2024 11:42:04 -0800
|
||||
Subject: [PATCH 22/31] libsysprof: check for PERF_REG_EXTENDED_MASK
|
||||
availability
|
||||
|
||||
---
|
||||
src/libsysprof/sysprof-user-sampler.c | 6 +++++-
|
||||
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/libsysprof/sysprof-user-sampler.c b/src/libsysprof/sysprof-user-sampler.c
|
||||
index 0e3afeae..a1418596 100644
|
||||
--- a/src/libsysprof/sysprof-user-sampler.c
|
||||
+++ b/src/libsysprof/sysprof-user-sampler.c
|
||||
@@ -48,7 +48,11 @@
|
||||
#define SYSPROF_ARCH_PREFERRED_REGS DWARF_NEEDED_REGS
|
||||
/* TODO: add other architectures, imitating the linux tools/perf tree */
|
||||
#else
|
||||
-# define SYSPROF_ARCH_PREFERRED_REGS PERF_REG_EXTENDED_MASK
|
||||
+# ifdef PERF_REG_EXTENDED_MASK
|
||||
+# define SYSPROF_ARCH_PREFERRED_REGS PERF_REG_EXTENDED_MASK
|
||||
+# else
|
||||
+# define SYSPROF_ARCH_PREFERRED_REGS 0
|
||||
+# endif
|
||||
#endif /* _ASM_{arch}_PERF_REGS_H */
|
||||
|
||||
#define N_WAKEUP_EVENTS 149
|
||||
--
|
||||
2.45.2
|
||||
|
38
0023-sysprof-live-unwinder-fix-source-func-prototype.patch
Normal file
38
0023-sysprof-live-unwinder-fix-source-func-prototype.patch
Normal file
@ -0,0 +1,38 @@
|
||||
From ed19a1b29cf6adc628432128bf6162c1446d5a46 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Hergert <chergert@redhat.com>
|
||||
Date: Tue, 12 Nov 2024 14:45:57 -0800
|
||||
Subject: [PATCH 23/31] sysprof-live-unwinder: fix source func prototype
|
||||
|
||||
While this looks like a GSource, the implementation type requires that
|
||||
it actually be a GUnixFDSourceFunc.
|
||||
---
|
||||
src/sysprof-live-unwinder/main.c | 6 ++++--
|
||||
1 file changed, 4 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/sysprof-live-unwinder/main.c b/src/sysprof-live-unwinder/main.c
|
||||
index 9e2733ae..e14eaf6c 100644
|
||||
--- a/src/sysprof-live-unwinder/main.c
|
||||
+++ b/src/sysprof-live-unwinder/main.c
|
||||
@@ -642,7 +642,9 @@ bump_to_max_fd_limit (void)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
-exit_callback (gpointer user_data)
|
||||
+exit_callback (int fd,
|
||||
+ GIOCondition condition,
|
||||
+ gpointer user_data)
|
||||
{
|
||||
g_main_loop_quit (user_data);
|
||||
return G_SOURCE_REMOVE;
|
||||
@@ -738,7 +740,7 @@ Examples:\n\
|
||||
g_autoptr(GSource) exit_source = g_unix_fd_source_new (event_fd, G_IO_IN);
|
||||
|
||||
g_source_set_callback (exit_source,
|
||||
- exit_callback,
|
||||
+ (GSourceFunc)exit_callback,
|
||||
g_main_loop_ref (main_loop),
|
||||
(GDestroyNotify) g_main_loop_unref);
|
||||
g_source_attach (exit_source, NULL);
|
||||
--
|
||||
2.45.2
|
||||
|
@ -0,0 +1,28 @@
|
||||
From 4b28282e30ee9ee483d3ed31a27956a5b35d2e95 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Hergert <chergert@redhat.com>
|
||||
Date: Wed, 13 Nov 2024 15:29:15 -0800
|
||||
Subject: [PATCH 24/31] sysprof-live-unwinder: handle large stack unwind sizes
|
||||
|
||||
---
|
||||
src/sysprof-live-unwinder/sysprof-live-unwinder.c | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
diff --git a/src/sysprof-live-unwinder/sysprof-live-unwinder.c b/src/sysprof-live-unwinder/sysprof-live-unwinder.c
|
||||
index c3b954b2..da77b0b0 100644
|
||||
--- a/src/sysprof-live-unwinder/sysprof-live-unwinder.c
|
||||
+++ b/src/sysprof-live-unwinder/sysprof-live-unwinder.c
|
||||
@@ -377,6 +377,11 @@ sysprof_live_unwinder_process_sampled_with_stack (SysprofLiveUnwinder *s
|
||||
return;
|
||||
}
|
||||
|
||||
+ /* We seem to get values > stack_size, which perhaps indicates we can
|
||||
+ * sometimes discover if we would not have gotten enough stack to unwind.
|
||||
+ */
|
||||
+ stack_dyn_size = MIN (stack_dyn_size, stack_size);
|
||||
+
|
||||
live_pid = sysprof_live_unwinder_find_pid (self, pid, TRUE);
|
||||
|
||||
/* Copy addresses over (which might be kernel, context-switch, etc until
|
||||
--
|
||||
2.45.2
|
||||
|
67
0025-unwinder-wait-for-completion-of-subprocess.patch
Normal file
67
0025-unwinder-wait-for-completion-of-subprocess.patch
Normal file
@ -0,0 +1,67 @@
|
||||
From 767e26c0aa2379312da5b029f924f765d90edce8 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Hergert <chergert@redhat.com>
|
||||
Date: Wed, 13 Nov 2024 15:46:01 -0800
|
||||
Subject: [PATCH 25/31] unwinder: wait for completion of subprocess
|
||||
|
||||
---
|
||||
src/sysprofd/ipc-unwinder-impl.c | 28 +++++++++++++++++++++++++++-
|
||||
1 file changed, 27 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/sysprofd/ipc-unwinder-impl.c b/src/sysprofd/ipc-unwinder-impl.c
|
||||
index 7f218de6..4341516b 100644
|
||||
--- a/src/sysprofd/ipc-unwinder-impl.c
|
||||
+++ b/src/sysprofd/ipc-unwinder-impl.c
|
||||
@@ -46,6 +46,25 @@ child_setup (gpointer data)
|
||||
prctl (PR_SET_PDEATHSIG, SIGKILL);
|
||||
}
|
||||
|
||||
+static void
|
||||
+ipc_unwinder_impl_wait_cb (GObject *object,
|
||||
+ GAsyncResult *result,
|
||||
+ gpointer user_data)
|
||||
+{
|
||||
+ GSubprocess *subprocess = (GSubprocess *)object;
|
||||
+ g_autoptr(IpcUnwinderImpl) self = user_data;
|
||||
+ g_autoptr(GError) error = NULL;
|
||||
+
|
||||
+ g_assert (G_IS_SUBPROCESS (subprocess));
|
||||
+ g_assert (G_IS_ASYNC_RESULT (result));
|
||||
+ g_assert (IPC_IS_UNWINDER_IMPL (self));
|
||||
+
|
||||
+ if (!g_subprocess_wait_check_finish (subprocess, result, &error))
|
||||
+ g_warning ("wait_check failure: %s", error->message);
|
||||
+ else
|
||||
+ g_info ("sysprof-live-unwinder exited");
|
||||
+}
|
||||
+
|
||||
static gboolean
|
||||
ipc_unwinder_impl_handle_unwind (IpcUnwinder *unwinder,
|
||||
GDBusMethodInvocation *invocation,
|
||||
@@ -155,16 +174,23 @@ ipc_unwinder_impl_handle_unwind (IpcUnwinder *unwinder,
|
||||
|
||||
if (!(subprocess = g_subprocess_launcher_spawnv (launcher, (const char * const *)argv->pdata, &error)))
|
||||
{
|
||||
+ g_critical ("Failed to start sysprof-live-unwinder: %s", error->message);
|
||||
g_dbus_method_invocation_return_gerror (g_steal_pointer (&invocation), error);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
+ g_message ("sysprof-live-unwinder started as process %s",
|
||||
+ g_subprocess_get_identifier (subprocess));
|
||||
+
|
||||
ipc_unwinder_complete_unwind (unwinder,
|
||||
g_steal_pointer (&invocation),
|
||||
out_fd_list,
|
||||
g_variant_new_handle (capture_fd_handle));
|
||||
|
||||
- g_subprocess_wait_async (subprocess, NULL, NULL, NULL);
|
||||
+ g_subprocess_wait_check_async (subprocess,
|
||||
+ NULL,
|
||||
+ ipc_unwinder_impl_wait_cb,
|
||||
+ g_object_ref (unwinder));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
--
|
||||
2.45.2
|
||||
|
227
0026-sysprof-user-sampler-implement-await-for-FDs.patch
Normal file
227
0026-sysprof-user-sampler-implement-await-for-FDs.patch
Normal file
@ -0,0 +1,227 @@
|
||||
From 12d0c969b83878d69f36255004b0dae6736a6c03 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Hergert <chergert@redhat.com>
|
||||
Date: Wed, 6 Nov 2024 15:09:13 -0800
|
||||
Subject: [PATCH 26/31] sysprof-user-sampler: implement await for FDs
|
||||
|
||||
This allows us to not need libdex 0.9+ for use by the sampler.
|
||||
---
|
||||
src/libsysprof/meson.build | 1 +
|
||||
src/libsysprof/sysprof-fd-private.h | 39 ++++++++++++++++
|
||||
src/libsysprof/sysprof-fd.c | 67 +++++++++++++++++++++++++++
|
||||
src/libsysprof/sysprof-user-sampler.c | 33 +++++++++++--
|
||||
4 files changed, 136 insertions(+), 4 deletions(-)
|
||||
create mode 100644 src/libsysprof/sysprof-fd-private.h
|
||||
create mode 100644 src/libsysprof/sysprof-fd.c
|
||||
|
||||
diff --git a/src/libsysprof/meson.build b/src/libsysprof/meson.build
|
||||
index e49c3a37..2ae977ca 100644
|
||||
--- a/src/libsysprof/meson.build
|
||||
+++ b/src/libsysprof/meson.build
|
||||
@@ -144,6 +144,7 @@ libsysprof_private_sources = [
|
||||
'sysprof-document-symbols.c',
|
||||
'sysprof-elf-loader.c',
|
||||
'sysprof-elf.c',
|
||||
+ 'sysprof-fd.c',
|
||||
'sysprof-leak-detector.c',
|
||||
'sysprof-maps-parser.c',
|
||||
'sysprof-mount-device.c',
|
||||
diff --git a/src/libsysprof/sysprof-fd-private.h b/src/libsysprof/sysprof-fd-private.h
|
||||
new file mode 100644
|
||||
index 00000000..1d4dfabc
|
||||
--- /dev/null
|
||||
+++ b/src/libsysprof/sysprof-fd-private.h
|
||||
@@ -0,0 +1,39 @@
|
||||
+/* sysprof-fd-private.h
|
||||
+ *
|
||||
+ * Copyright 2024 Christian Hergert <chergert@redhat.com>
|
||||
+ *
|
||||
+ * This library is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU Lesser General Public License as
|
||||
+ * published by the Free Software Foundation; either version 2.1 of the
|
||||
+ * License, or (at your option) any later version.
|
||||
+ *
|
||||
+ * This library is distributed in the hope that it will be useful, but
|
||||
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ * Lesser General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License along
|
||||
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
+ *
|
||||
+ * SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
+ */
|
||||
+
|
||||
+#pragma once
|
||||
+
|
||||
+#include <glib-object.h>
|
||||
+
|
||||
+G_BEGIN_DECLS
|
||||
+
|
||||
+#define SYSPROF_TYPE_FD (sysprof_fd_get_type())
|
||||
+
|
||||
+typedef struct _SysprofFD SysprofFD;
|
||||
+
|
||||
+GType sysprof_fd_get_type (void) G_GNUC_CONST;
|
||||
+int sysprof_fd_peek (const SysprofFD *fd);
|
||||
+int sysprof_fd_steal (SysprofFD *fd);
|
||||
+SysprofFD *sysprof_fd_dup (const SysprofFD *fd);
|
||||
+void sysprof_fd_free (SysprofFD *fd);
|
||||
+
|
||||
+G_DEFINE_AUTOPTR_CLEANUP_FUNC (SysprofFD, sysprof_fd_free)
|
||||
+
|
||||
+G_END_DECLS
|
||||
diff --git a/src/libsysprof/sysprof-fd.c b/src/libsysprof/sysprof-fd.c
|
||||
new file mode 100644
|
||||
index 00000000..5e34f8d9
|
||||
--- /dev/null
|
||||
+++ b/src/libsysprof/sysprof-fd.c
|
||||
@@ -0,0 +1,67 @@
|
||||
+/* sysprof-fd.c
|
||||
+ *
|
||||
+ * Copyright 2024 Christian Hergert <chergert@redhat.com>
|
||||
+ *
|
||||
+ * This library is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU Lesser General Public License as
|
||||
+ * published by the Free Software Foundation; either version 2.1 of the
|
||||
+ * License, or (at your option) any later version.
|
||||
+ *
|
||||
+ * This library is distributed in the hope that it will be useful, but
|
||||
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ * Lesser General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License along
|
||||
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
+ *
|
||||
+ * SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
+ */
|
||||
+
|
||||
+#include "config.h"
|
||||
+
|
||||
+#include <unistd.h>
|
||||
+
|
||||
+#include "sysprof-fd-private.h"
|
||||
+
|
||||
+int
|
||||
+sysprof_fd_peek (const SysprofFD *fd)
|
||||
+{
|
||||
+ if (fd == NULL)
|
||||
+ return -1;
|
||||
+
|
||||
+ return *(int *)fd;
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+sysprof_fd_steal (SysprofFD *fd)
|
||||
+{
|
||||
+ if (fd == NULL)
|
||||
+ return -1;
|
||||
+
|
||||
+ return g_steal_fd ((int *)fd);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+sysprof_fd_free (SysprofFD *fd)
|
||||
+{
|
||||
+ int real = sysprof_fd_steal (fd);
|
||||
+ if (real != -1)
|
||||
+ close (real);
|
||||
+ g_free (fd);
|
||||
+}
|
||||
+
|
||||
+SysprofFD *
|
||||
+sysprof_fd_dup (const SysprofFD *fd)
|
||||
+{
|
||||
+ int real = sysprof_fd_peek (fd);
|
||||
+
|
||||
+ if (real == -1)
|
||||
+ return NULL;
|
||||
+
|
||||
+ real = dup (real);
|
||||
+
|
||||
+ return g_memdup2 (&real, sizeof real);
|
||||
+}
|
||||
+
|
||||
+G_DEFINE_BOXED_TYPE (SysprofFD, sysprof_fd, sysprof_fd_dup, sysprof_fd_free)
|
||||
diff --git a/src/libsysprof/sysprof-user-sampler.c b/src/libsysprof/sysprof-user-sampler.c
|
||||
index a1418596..44b4d318 100644
|
||||
--- a/src/libsysprof/sysprof-user-sampler.c
|
||||
+++ b/src/libsysprof/sysprof-user-sampler.c
|
||||
@@ -32,6 +32,7 @@
|
||||
#include "sysprof-recording-private.h"
|
||||
#include "sysprof-user-sampler.h"
|
||||
#include "sysprof-muxer-source.h"
|
||||
+#include "sysprof-fd-private.h"
|
||||
|
||||
#include "ipc-unwinder.h"
|
||||
|
||||
@@ -85,6 +86,30 @@ close_fd (gpointer data)
|
||||
}
|
||||
}
|
||||
|
||||
+static void
|
||||
+promise_resolve_fd (DexPromise *promise,
|
||||
+ int fd)
|
||||
+{
|
||||
+ GValue gvalue = {SYSPROF_TYPE_FD, {{.v_pointer = &fd}, {.v_int = 0}}};
|
||||
+ dex_promise_resolve (promise, &gvalue);
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+await_fd (DexFuture *future,
|
||||
+ GError **error)
|
||||
+{
|
||||
+ SysprofFD *fd = dex_await_boxed (future, error);
|
||||
+ int ret = -1;
|
||||
+
|
||||
+ if (fd != NULL)
|
||||
+ {
|
||||
+ ret = sysprof_fd_steal (fd);
|
||||
+ sysprof_fd_free (fd);
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
static void
|
||||
sysprof_user_sampler_ioctl (SysprofUserSampler *self,
|
||||
gboolean enable)
|
||||
@@ -149,7 +174,7 @@ _perf_event_open_cb (GObject *object,
|
||||
if (-1 == (fd = g_unix_fd_list_get (fd_list, handle, &error)))
|
||||
goto failure;
|
||||
|
||||
- dex_promise_resolve_fd (promise, g_steal_fd (&fd));
|
||||
+ promise_resolve_fd (promise, g_steal_fd (&fd));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -234,7 +259,7 @@ try_again:
|
||||
_perf_event_open_cb,
|
||||
dex_ref (promise));
|
||||
|
||||
- if (-1 == (perf_fd = dex_await_fd (dex_ref (promise), error)))
|
||||
+ if (-1 == (perf_fd = await_fd (dex_ref (promise), error)))
|
||||
{
|
||||
g_clear_pointer (&options, g_variant_unref);
|
||||
|
||||
@@ -274,7 +299,7 @@ call_unwind_cb (GObject *object,
|
||||
|
||||
if (ipc_unwinder_call_unwind_finish (IPC_UNWINDER (object), &out_capture_fd, &out_fd_list, result, &error) &&
|
||||
-1 != (capture_fd = g_unix_fd_list_get (out_fd_list, g_variant_get_handle (out_capture_fd), &error)))
|
||||
- dex_promise_resolve_fd (promise, g_steal_fd (&capture_fd));
|
||||
+ promise_resolve_fd (promise, g_steal_fd (&capture_fd));
|
||||
else
|
||||
dex_promise_reject (promise, error);
|
||||
}
|
||||
@@ -406,7 +431,7 @@ sysprof_user_sampler_prepare_fiber (gpointer user_data)
|
||||
call_unwind_cb,
|
||||
dex_ref (promise));
|
||||
|
||||
- fd = dex_await_fd (dex_ref (promise), &error);
|
||||
+ fd = await_fd (dex_ref (promise), &error);
|
||||
|
||||
if (fd == -1)
|
||||
{
|
||||
--
|
||||
2.45.2
|
||||
|
276
0027-libsysprof-provide-unwind-pipe-from-client.patch
Normal file
276
0027-libsysprof-provide-unwind-pipe-from-client.patch
Normal file
@ -0,0 +1,276 @@
|
||||
From 6812ec432141fbdf0754e90d1e7a3d5667b14bf0 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Hergert <chergert@redhat.com>
|
||||
Date: Wed, 13 Nov 2024 15:40:52 -0800
|
||||
Subject: [PATCH 27/31] libsysprof: provide unwind pipe from client
|
||||
|
||||
We don't need a socketpair for this. Additionally, things seem to work
|
||||
better from the service when the client provides the pipe. Otherwise, when
|
||||
running as a dbus service I often have issues with things getting closed
|
||||
out from under us.
|
||||
---
|
||||
src/libsysprof/sysprof-user-sampler.c | 65 ++++++++++++--------
|
||||
src/sysprofd/ipc-unwinder-impl.c | 46 +++-----------
|
||||
src/sysprofd/org.gnome.Sysprof3.Unwinder.xml | 2 +-
|
||||
3 files changed, 48 insertions(+), 65 deletions(-)
|
||||
|
||||
diff --git a/src/libsysprof/sysprof-user-sampler.c b/src/libsysprof/sysprof-user-sampler.c
|
||||
index 44b4d318..6079708e 100644
|
||||
--- a/src/libsysprof/sysprof-user-sampler.c
|
||||
+++ b/src/libsysprof/sysprof-user-sampler.c
|
||||
@@ -20,6 +20,8 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
+#include <fcntl.h>
|
||||
+
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/eventfd.h>
|
||||
|
||||
@@ -62,7 +64,8 @@ struct _SysprofUserSampler
|
||||
{
|
||||
SysprofInstrument parent_instance;
|
||||
GArray *perf_fds;
|
||||
- int capture_fd;
|
||||
+ int capture_fd_read;
|
||||
+ int capture_fd_write;
|
||||
int event_fd;
|
||||
guint stack_size;
|
||||
};
|
||||
@@ -289,17 +292,14 @@ call_unwind_cb (GObject *object,
|
||||
{
|
||||
g_autoptr(DexPromise) promise = user_data;
|
||||
g_autoptr(GUnixFDList) out_fd_list = NULL;
|
||||
- g_autoptr(GVariant) out_capture_fd = NULL;
|
||||
- g_autofd int capture_fd = -1;
|
||||
GError *error = NULL;
|
||||
|
||||
g_assert (IPC_IS_UNWINDER (object));
|
||||
g_assert (G_IS_ASYNC_RESULT (result));
|
||||
g_assert (DEX_IS_PROMISE (promise));
|
||||
|
||||
- if (ipc_unwinder_call_unwind_finish (IPC_UNWINDER (object), &out_capture_fd, &out_fd_list, result, &error) &&
|
||||
- -1 != (capture_fd = g_unix_fd_list_get (out_fd_list, g_variant_get_handle (out_capture_fd), &error)))
|
||||
- promise_resolve_fd (promise, g_steal_fd (&capture_fd));
|
||||
+ if (ipc_unwinder_call_unwind_finish (IPC_UNWINDER (object), &out_fd_list, result, &error))
|
||||
+ dex_promise_resolve_boolean (promise, TRUE);
|
||||
else
|
||||
dex_promise_reject (promise, error);
|
||||
}
|
||||
@@ -420,31 +420,26 @@ sysprof_user_sampler_prepare_fiber (gpointer user_data)
|
||||
{
|
||||
g_autoptr(DexPromise) promise = dex_promise_new ();
|
||||
int event_fd_handle = g_unix_fd_list_append (fd_list, prepare->sampler->event_fd, NULL);
|
||||
- g_autofd int fd = -1;
|
||||
+ int capture_fd_handle = g_unix_fd_list_append (fd_list, prepare->sampler->capture_fd_write, NULL);
|
||||
|
||||
ipc_unwinder_call_unwind (unwinder,
|
||||
prepare->stack_size,
|
||||
g_variant_builder_end (&builder),
|
||||
g_variant_new_handle (event_fd_handle),
|
||||
+ g_variant_new_handle (capture_fd_handle),
|
||||
fd_list,
|
||||
NULL,
|
||||
call_unwind_cb,
|
||||
dex_ref (promise));
|
||||
|
||||
- fd = await_fd (dex_ref (promise), &error);
|
||||
-
|
||||
- if (fd == -1)
|
||||
+ if (!dex_await (dex_ref (promise), &error))
|
||||
{
|
||||
_sysprof_recording_diagnostic (prepare->recording,
|
||||
"Sampler",
|
||||
- "Failed to setup user-space unwinder: %s",
|
||||
+ "Failed to setup thread unwinder: %s",
|
||||
error->message);
|
||||
g_clear_error (&error);
|
||||
}
|
||||
- else
|
||||
- {
|
||||
- prepare->sampler->capture_fd = g_steal_fd (&fd);
|
||||
- }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -506,21 +501,26 @@ sysprof_user_sampler_record_fiber (gpointer user_data)
|
||||
|
||||
writer = _sysprof_recording_writer (record->recording);
|
||||
|
||||
- sysprof_user_sampler_ioctl (record->sampler, TRUE);
|
||||
+ if (record->sampler->capture_fd_read != -1)
|
||||
+ {
|
||||
+ sysprof_user_sampler_ioctl (record->sampler, TRUE);
|
||||
|
||||
- g_debug ("Staring muxer for capture_fd");
|
||||
- muxer_source = sysprof_muxer_source_new (g_steal_fd (&record->sampler->capture_fd), writer);
|
||||
- g_source_set_static_name (muxer_source, "[stack-muxer]");
|
||||
- g_source_attach (muxer_source, NULL);
|
||||
+ g_debug ("Staring muxer for capture_fd %d", record->sampler->capture_fd_read);
|
||||
+ muxer_source = sysprof_muxer_source_new (g_steal_fd (&record->sampler->capture_fd_read), writer);
|
||||
+ g_source_set_static_name (muxer_source, "[stack-muxer]");
|
||||
+ g_source_attach (muxer_source, NULL);
|
||||
|
||||
- if (!dex_await (dex_ref (record->cancellable), &error))
|
||||
- g_debug ("UserSampler shutting down for reason: %s", error->message);
|
||||
+ if (!dex_await (dex_ref (record->cancellable), &error))
|
||||
+ g_debug ("UserSampler shutting down for reason: %s", error->message);
|
||||
|
||||
- write (record->sampler->event_fd, &exiting, sizeof exiting);
|
||||
+ write (record->sampler->event_fd, &exiting, sizeof exiting);
|
||||
|
||||
- g_source_destroy (muxer_source);
|
||||
+ g_source_destroy (muxer_source);
|
||||
|
||||
- sysprof_user_sampler_ioctl (record->sampler, FALSE);
|
||||
+ sysprof_user_sampler_ioctl (record->sampler, FALSE);
|
||||
+ }
|
||||
+ else
|
||||
+ g_warning ("No capture FD available for muxing");
|
||||
|
||||
return dex_future_new_for_boolean (TRUE);
|
||||
}
|
||||
@@ -555,7 +555,8 @@ sysprof_user_sampler_finalize (GObject *object)
|
||||
|
||||
g_clear_pointer (&self->perf_fds, g_array_unref);
|
||||
|
||||
- g_clear_fd (&self->capture_fd, NULL);
|
||||
+ g_clear_fd (&self->capture_fd_read, NULL);
|
||||
+ g_clear_fd (&self->capture_fd_write, NULL);
|
||||
g_clear_fd (&self->event_fd, NULL);
|
||||
|
||||
G_OBJECT_CLASS (sysprof_user_sampler_parent_class)->finalize (object);
|
||||
@@ -577,9 +578,19 @@ sysprof_user_sampler_class_init (SysprofUserSamplerClass *klass)
|
||||
static void
|
||||
sysprof_user_sampler_init (SysprofUserSampler *self)
|
||||
{
|
||||
- self->capture_fd = -1;
|
||||
+ int fds[2];
|
||||
+
|
||||
self->event_fd = eventfd (0, EFD_CLOEXEC);
|
||||
|
||||
+ self->capture_fd_read = -1;
|
||||
+ self->capture_fd_write = -1;
|
||||
+
|
||||
+ if (pipe2 (fds, O_CLOEXEC) == 0)
|
||||
+ {
|
||||
+ self->capture_fd_read = fds[0];
|
||||
+ self->capture_fd_write = fds[1];
|
||||
+ }
|
||||
+
|
||||
self->perf_fds = g_array_new (FALSE, FALSE, sizeof (int));
|
||||
g_array_set_clear_func (self->perf_fds, close_fd);
|
||||
}
|
||||
diff --git a/src/sysprofd/ipc-unwinder-impl.c b/src/sysprofd/ipc-unwinder-impl.c
|
||||
index 4341516b..e6a0d7ab 100644
|
||||
--- a/src/sysprofd/ipc-unwinder-impl.c
|
||||
+++ b/src/sysprofd/ipc-unwinder-impl.c
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#include <errno.h>
|
||||
+#include <fcntl.h>
|
||||
|
||||
#include <signal.h>
|
||||
#include <sys/prctl.h>
|
||||
@@ -71,19 +72,16 @@ ipc_unwinder_impl_handle_unwind (IpcUnwinder *unwinder,
|
||||
GUnixFDList *fd_list,
|
||||
guint stack_size,
|
||||
GVariant *arg_perf_fds,
|
||||
- GVariant *arg_event_fd)
|
||||
+ GVariant *arg_event_fd,
|
||||
+ GVariant *arg_capture_fd)
|
||||
{
|
||||
g_autoptr(GSubprocessLauncher) launcher = NULL;
|
||||
g_autoptr(GSubprocess) subprocess = NULL;
|
||||
- g_autoptr(GUnixFDList) out_fd_list = NULL;
|
||||
g_autoptr(GPtrArray) argv = NULL;
|
||||
g_autoptr(GError) error = NULL;
|
||||
- g_autofd int our_fd = -1;
|
||||
- g_autofd int their_fd = -1;
|
||||
+ g_autofd int capture_fd = -1;
|
||||
g_autofd int event_fd = -1;
|
||||
GVariantIter iter;
|
||||
- int capture_fd_handle;
|
||||
- int pair[2];
|
||||
int next_target_fd = 3;
|
||||
int perf_fd_handle;
|
||||
int cpu;
|
||||
@@ -116,13 +114,14 @@ ipc_unwinder_impl_handle_unwind (IpcUnwinder *unwinder,
|
||||
g_ptr_array_add (argv, g_strdup (PACKAGE_LIBEXECDIR "/sysprof-live-unwinder"));
|
||||
g_ptr_array_add (argv, g_strdup_printf ("--stack-size=%u", stack_size));
|
||||
|
||||
- if (-1 == (event_fd = g_unix_fd_list_get (fd_list, g_variant_get_handle (arg_event_fd), &error)))
|
||||
+ if (-1 == (event_fd = g_unix_fd_list_get (fd_list, g_variant_get_handle (arg_event_fd), &error)) ||
|
||||
+ -1 == (capture_fd = g_unix_fd_list_get (fd_list, g_variant_get_handle (arg_capture_fd), &error)))
|
||||
{
|
||||
g_dbus_method_invocation_return_gerror (g_steal_pointer (&invocation), error);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
- g_ptr_array_add (argv, g_strdup_printf ("--event-fd=%u", next_target_fd));
|
||||
+ g_ptr_array_add (argv, g_strdup_printf ("--event-fd=%d", next_target_fd));
|
||||
g_subprocess_launcher_take_fd (launcher, g_steal_fd (&event_fd), next_target_fd++);
|
||||
|
||||
g_variant_iter_init (&iter, arg_perf_fds);
|
||||
@@ -143,32 +142,8 @@ ipc_unwinder_impl_handle_unwind (IpcUnwinder *unwinder,
|
||||
next_target_fd++);
|
||||
}
|
||||
|
||||
- g_subprocess_launcher_set_child_setup (launcher, child_setup, NULL, NULL);
|
||||
-
|
||||
- if (socketpair (AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, pair) < 0)
|
||||
- {
|
||||
- int errsv = errno;
|
||||
- g_dbus_method_invocation_return_error_literal (g_steal_pointer (&invocation),
|
||||
- G_IO_ERROR,
|
||||
- g_io_error_from_errno (errsv),
|
||||
- g_strerror (errsv));
|
||||
- return TRUE;
|
||||
- }
|
||||
-
|
||||
- our_fd = g_steal_fd (&pair[0]);
|
||||
- their_fd = g_steal_fd (&pair[1]);
|
||||
-
|
||||
- out_fd_list = g_unix_fd_list_new ();
|
||||
- capture_fd_handle = g_unix_fd_list_append (out_fd_list, their_fd, &error);
|
||||
-
|
||||
- if (capture_fd_handle < 0)
|
||||
- {
|
||||
- g_dbus_method_invocation_return_gerror (g_steal_pointer (&invocation), error);
|
||||
- return TRUE;
|
||||
- }
|
||||
-
|
||||
g_ptr_array_add (argv, g_strdup_printf ("--capture-fd=%d", next_target_fd));
|
||||
- g_subprocess_launcher_take_fd (launcher, g_steal_fd (&our_fd), next_target_fd++);
|
||||
+ g_subprocess_launcher_take_fd (launcher, g_steal_fd (&capture_fd), next_target_fd++);
|
||||
|
||||
g_ptr_array_add (argv, NULL);
|
||||
|
||||
@@ -182,10 +157,7 @@ ipc_unwinder_impl_handle_unwind (IpcUnwinder *unwinder,
|
||||
g_message ("sysprof-live-unwinder started as process %s",
|
||||
g_subprocess_get_identifier (subprocess));
|
||||
|
||||
- ipc_unwinder_complete_unwind (unwinder,
|
||||
- g_steal_pointer (&invocation),
|
||||
- out_fd_list,
|
||||
- g_variant_new_handle (capture_fd_handle));
|
||||
+ ipc_unwinder_complete_unwind (unwinder, g_steal_pointer (&invocation), NULL);
|
||||
|
||||
g_subprocess_wait_check_async (subprocess,
|
||||
NULL,
|
||||
diff --git a/src/sysprofd/org.gnome.Sysprof3.Unwinder.xml b/src/sysprofd/org.gnome.Sysprof3.Unwinder.xml
|
||||
index fb2c7848..86b3bdbe 100644
|
||||
--- a/src/sysprofd/org.gnome.Sysprof3.Unwinder.xml
|
||||
+++ b/src/sysprofd/org.gnome.Sysprof3.Unwinder.xml
|
||||
@@ -17,7 +17,7 @@
|
||||
<arg type="u" name="stack_size" direction="in"/>
|
||||
<arg type="a(hi)" name="perf_fds" direction="in"/>
|
||||
<arg type="h" name="event_fd" direction="in"/>
|
||||
- <arg type="h" name="capture_fd" direction="out"/>
|
||||
+ <arg type="h" name="capture_fd" direction="in"/>
|
||||
</method>
|
||||
</interface>
|
||||
</node>
|
||||
--
|
||||
2.45.2
|
||||
|
@ -0,0 +1,31 @@
|
||||
From 6cdafd91ef71b15af66107b37a5db6b5a3dcd319 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Hergert <chergert@redhat.com>
|
||||
Date: Wed, 13 Nov 2024 15:41:33 -0800
|
||||
Subject: [PATCH 28/31] sysprof-live-unwinder: error out on capture failure
|
||||
|
||||
---
|
||||
src/sysprof-live-unwinder/main.c | 8 +++++++-
|
||||
1 file changed, 7 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/sysprof-live-unwinder/main.c b/src/sysprof-live-unwinder/main.c
|
||||
index e14eaf6c..a1cd53fa 100644
|
||||
--- a/src/sysprof-live-unwinder/main.c
|
||||
+++ b/src/sysprof-live-unwinder/main.c
|
||||
@@ -708,7 +708,13 @@ Examples:\n\
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
- writer = sysprof_capture_writer_new_from_fd (g_steal_fd (&capture_fd), CAPTURE_BUFFER_SIZE);
|
||||
+ if (!(writer = sysprof_capture_writer_new_from_fd (g_steal_fd (&capture_fd), CAPTURE_BUFFER_SIZE)))
|
||||
+ {
|
||||
+ int errsv = errno;
|
||||
+ g_printerr ("Failed to create capture writer: %s\n",
|
||||
+ g_strerror (errsv));
|
||||
+ return EXIT_FAILURE;
|
||||
+ }
|
||||
|
||||
if (all_perf_fds->len == 0)
|
||||
{
|
||||
--
|
||||
2.45.2
|
||||
|
37
0029-sysprofd-remove-unused-code.patch
Normal file
37
0029-sysprofd-remove-unused-code.patch
Normal file
@ -0,0 +1,37 @@
|
||||
From d2d0467c28a4c2b9288cec5cfa83c42ec94c533f Mon Sep 17 00:00:00 2001
|
||||
From: Christian Hergert <chergert@redhat.com>
|
||||
Date: Wed, 13 Nov 2024 15:53:12 -0800
|
||||
Subject: [PATCH 29/31] sysprofd: remove unused code
|
||||
|
||||
---
|
||||
src/sysprofd/ipc-unwinder-impl.c | 7 -------
|
||||
1 file changed, 7 deletions(-)
|
||||
|
||||
diff --git a/src/sysprofd/ipc-unwinder-impl.c b/src/sysprofd/ipc-unwinder-impl.c
|
||||
index e6a0d7ab..2290377b 100644
|
||||
--- a/src/sysprofd/ipc-unwinder-impl.c
|
||||
+++ b/src/sysprofd/ipc-unwinder-impl.c
|
||||
@@ -27,7 +27,6 @@
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <signal.h>
|
||||
-#include <sys/prctl.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <glib/gstdio.h>
|
||||
@@ -41,12 +40,6 @@ struct _IpcUnwinderImpl
|
||||
IpcUnwinderSkeleton parent_instance;
|
||||
};
|
||||
|
||||
-static void
|
||||
-child_setup (gpointer data)
|
||||
-{
|
||||
- prctl (PR_SET_PDEATHSIG, SIGKILL);
|
||||
-}
|
||||
-
|
||||
static void
|
||||
ipc_unwinder_impl_wait_cb (GObject *object,
|
||||
GAsyncResult *result,
|
||||
--
|
||||
2.45.2
|
||||
|
@ -0,0 +1,26 @@
|
||||
From 2ab855d5fdfd70948e6deeef3cfafb759d1c91f7 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Hergert <chergert@redhat.com>
|
||||
Date: Wed, 13 Nov 2024 15:54:12 -0800
|
||||
Subject: [PATCH 30/31] build: lower libpanel requirement to ease some build
|
||||
systems
|
||||
|
||||
---
|
||||
src/sysprof/meson.build | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/sysprof/meson.build b/src/sysprof/meson.build
|
||||
index ab6a701a..62f3441f 100644
|
||||
--- a/src/sysprof/meson.build
|
||||
+++ b/src/sysprof/meson.build
|
||||
@@ -88,7 +88,7 @@ sysprof_deps = [
|
||||
cc.find_library('m', required: false),
|
||||
dependency('gtk4', version: gtk_req_version),
|
||||
dependency('libadwaita-1', version: '>= 1.6.0'),
|
||||
- dependency('libpanel-1', version: '>= 1.7.0'),
|
||||
+ dependency('libpanel-1', version: '>= 1.4'),
|
||||
|
||||
libsysprof_static_dep,
|
||||
]
|
||||
--
|
||||
2.45.2
|
||||
|
168
0031-build-allow-await-for-FD-with-older-libdex.patch
Normal file
168
0031-build-allow-await-for-FD-with-older-libdex.patch
Normal file
@ -0,0 +1,168 @@
|
||||
From d34689ff54650a581a2af3595a6f42c7d5c0166e Mon Sep 17 00:00:00 2001
|
||||
From: Christian Hergert <chergert@redhat.com>
|
||||
Date: Wed, 13 Nov 2024 16:20:06 -0800
|
||||
Subject: [PATCH 31/31] build: allow await for FD with older libdex
|
||||
|
||||
This just makes backports easier.
|
||||
---
|
||||
meson.build | 2 +-
|
||||
src/libsysprof/sysprof-fd-private.h | 7 +++++
|
||||
src/libsysprof/sysprof-fd.c | 24 ++++++++++++++++
|
||||
src/libsysprof/sysprof-user-sampler.c | 28 ++-----------------
|
||||
.../tests/test-live-unwinder.c | 5 ++--
|
||||
5 files changed, 37 insertions(+), 29 deletions(-)
|
||||
|
||||
diff --git a/meson.build b/meson.build
|
||||
index 16d64e8a..e2a9a995 100644
|
||||
--- a/meson.build
|
||||
+++ b/meson.build
|
||||
@@ -45,7 +45,7 @@ need_libsysprof = (need_gtk or
|
||||
get_option('tools') or
|
||||
get_option('tests'))
|
||||
|
||||
-dex_req = '0.9'
|
||||
+dex_req = '0.8'
|
||||
glib_req = '2.76.0'
|
||||
gtk_req = '4.15'
|
||||
polkit_req = '0.105'
|
||||
diff --git a/src/libsysprof/sysprof-fd-private.h b/src/libsysprof/sysprof-fd-private.h
|
||||
index 1d4dfabc..f6f11b0c 100644
|
||||
--- a/src/libsysprof/sysprof-fd-private.h
|
||||
+++ b/src/libsysprof/sysprof-fd-private.h
|
||||
@@ -22,6 +22,8 @@
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
+#include <libdex.h>
|
||||
+
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define SYSPROF_TYPE_FD (sysprof_fd_get_type())
|
||||
@@ -36,4 +38,9 @@ void sysprof_fd_free (SysprofFD *fd);
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (SysprofFD, sysprof_fd_free)
|
||||
|
||||
+int sysprof_await_fd (DexFuture *future,
|
||||
+ GError **error);
|
||||
+void sysprof_promise_resolve_fd (DexPromise *promise,
|
||||
+ int fd);
|
||||
+
|
||||
G_END_DECLS
|
||||
diff --git a/src/libsysprof/sysprof-fd.c b/src/libsysprof/sysprof-fd.c
|
||||
index 5e34f8d9..a571cefe 100644
|
||||
--- a/src/libsysprof/sysprof-fd.c
|
||||
+++ b/src/libsysprof/sysprof-fd.c
|
||||
@@ -65,3 +65,27 @@ sysprof_fd_dup (const SysprofFD *fd)
|
||||
}
|
||||
|
||||
G_DEFINE_BOXED_TYPE (SysprofFD, sysprof_fd, sysprof_fd_dup, sysprof_fd_free)
|
||||
+
|
||||
+void
|
||||
+sysprof_promise_resolve_fd (DexPromise *promise,
|
||||
+ int fd)
|
||||
+{
|
||||
+ GValue gvalue = {SYSPROF_TYPE_FD, {{.v_pointer = &fd}, {.v_int = 0}}};
|
||||
+ dex_promise_resolve (promise, &gvalue);
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+sysprof_await_fd (DexFuture *future,
|
||||
+ GError **error)
|
||||
+{
|
||||
+ SysprofFD *fd = dex_await_boxed (future, error);
|
||||
+ int ret = -1;
|
||||
+
|
||||
+ if (fd != NULL)
|
||||
+ {
|
||||
+ ret = sysprof_fd_steal (fd);
|
||||
+ sysprof_fd_free (fd);
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
diff --git a/src/libsysprof/sysprof-user-sampler.c b/src/libsysprof/sysprof-user-sampler.c
|
||||
index 6079708e..05f97cbf 100644
|
||||
--- a/src/libsysprof/sysprof-user-sampler.c
|
||||
+++ b/src/libsysprof/sysprof-user-sampler.c
|
||||
@@ -89,30 +89,6 @@ close_fd (gpointer data)
|
||||
}
|
||||
}
|
||||
|
||||
-static void
|
||||
-promise_resolve_fd (DexPromise *promise,
|
||||
- int fd)
|
||||
-{
|
||||
- GValue gvalue = {SYSPROF_TYPE_FD, {{.v_pointer = &fd}, {.v_int = 0}}};
|
||||
- dex_promise_resolve (promise, &gvalue);
|
||||
-}
|
||||
-
|
||||
-static int
|
||||
-await_fd (DexFuture *future,
|
||||
- GError **error)
|
||||
-{
|
||||
- SysprofFD *fd = dex_await_boxed (future, error);
|
||||
- int ret = -1;
|
||||
-
|
||||
- if (fd != NULL)
|
||||
- {
|
||||
- ret = sysprof_fd_steal (fd);
|
||||
- sysprof_fd_free (fd);
|
||||
- }
|
||||
-
|
||||
- return ret;
|
||||
-}
|
||||
-
|
||||
static void
|
||||
sysprof_user_sampler_ioctl (SysprofUserSampler *self,
|
||||
gboolean enable)
|
||||
@@ -177,7 +153,7 @@ _perf_event_open_cb (GObject *object,
|
||||
if (-1 == (fd = g_unix_fd_list_get (fd_list, handle, &error)))
|
||||
goto failure;
|
||||
|
||||
- promise_resolve_fd (promise, g_steal_fd (&fd));
|
||||
+ sysprof_promise_resolve_fd (promise, g_steal_fd (&fd));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -262,7 +238,7 @@ try_again:
|
||||
_perf_event_open_cb,
|
||||
dex_ref (promise));
|
||||
|
||||
- if (-1 == (perf_fd = await_fd (dex_ref (promise), error)))
|
||||
+ if (-1 == (perf_fd = sysprof_await_fd (dex_ref (promise), error)))
|
||||
{
|
||||
g_clear_pointer (&options, g_variant_unref);
|
||||
|
||||
diff --git a/src/sysprof-live-unwinder/tests/test-live-unwinder.c b/src/sysprof-live-unwinder/tests/test-live-unwinder.c
|
||||
index 114cc568..c3eda85a 100644
|
||||
--- a/src/sysprof-live-unwinder/tests/test-live-unwinder.c
|
||||
+++ b/src/sysprof-live-unwinder/tests/test-live-unwinder.c
|
||||
@@ -33,6 +33,7 @@
|
||||
|
||||
#include <sysprof.h>
|
||||
|
||||
+#include "sysprof-fd-private.h"
|
||||
#include "sysprof-perf-event-stream-private.h"
|
||||
|
||||
#if HAVE_POLKIT_AGENT
|
||||
@@ -89,7 +90,7 @@ open_perf_stream_cb (GObject *object,
|
||||
|
||||
if (-1 != (fd = g_unix_fd_list_get (fd_list, handle, &error)))
|
||||
{
|
||||
- dex_promise_resolve_fd (promise, g_steal_fd (&fd));
|
||||
+ sysprof_promise_resolve_fd (promise, g_steal_fd (&fd));
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -179,7 +180,7 @@ try_again:
|
||||
open_perf_stream_cb,
|
||||
dex_ref (promise));
|
||||
|
||||
- fd = dex_await_fd (dex_ref (promise), error);
|
||||
+ fd = sysprof_await_fd (dex_ref (promise), error);
|
||||
|
||||
if (*error == NULL)
|
||||
{
|
||||
--
|
||||
2.45.2
|
||||
|
37
0032-sysprof-default-stack-capturing-as-enabled.patch
Normal file
37
0032-sysprof-default-stack-capturing-as-enabled.patch
Normal file
@ -0,0 +1,37 @@
|
||||
From 99f807240e4be653a122b9e443cd38782962bc59 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Hergert <chergert@redhat.com>
|
||||
Date: Wed, 6 Nov 2024 13:09:31 -0800
|
||||
Subject: [PATCH] sysprof: default stack-capturing as enabled
|
||||
|
||||
This is for CentOS/RHEL only as other distributions have frame-pointers.
|
||||
---
|
||||
src/sysprof/sysprof-recording-template.c | 6 +++++-
|
||||
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/sysprof/sysprof-recording-template.c b/src/sysprof/sysprof-recording-template.c
|
||||
index ee4d4f01..b3018763 100644
|
||||
--- a/src/sysprof/sysprof-recording-template.c
|
||||
+++ b/src/sysprof/sysprof-recording-template.c
|
||||
@@ -446,7 +446,8 @@ sysprof_recording_template_class_init (SysprofRecordingTemplateClass *klass)
|
||||
|
||||
properties[PROP_USER_STACKS] =
|
||||
g_param_spec_boolean ("user-stacks", NULL, NULL,
|
||||
- FALSE,
|
||||
+ /* Default to stack capturing in CentOS/RHEL */
|
||||
+ TRUE,
|
||||
(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
properties[PROP_STACK_SIZE] =
|
||||
@@ -473,6 +474,9 @@ sysprof_recording_template_init (SysprofRecordingTemplate *self)
|
||||
self->command_line = g_strdup ("");
|
||||
self->cwd = g_strdup("");
|
||||
self->stack_size = DEFAULT_STACK_SIZE;
|
||||
+
|
||||
+ /* Default to stack capturing in CentOS/RHEL */
|
||||
+ self->user_stacks = TRUE;
|
||||
}
|
||||
|
||||
SysprofRecordingTemplate *
|
||||
--
|
||||
2.45.2
|
||||
|
29
0033-tests-fix-test-on-s390.patch
Normal file
29
0033-tests-fix-test-on-s390.patch
Normal file
@ -0,0 +1,29 @@
|
||||
From 08d94d9b982e5d4a6e7a67b45ae71bd51ca3fe0d Mon Sep 17 00:00:00 2001
|
||||
From: Christian Hergert <chergert@redhat.com>
|
||||
Date: Wed, 13 Nov 2024 17:16:44 -0800
|
||||
Subject: [PATCH] tests: fix test on s390
|
||||
|
||||
---
|
||||
src/sysprof-live-unwinder/tests/test-live-unwinder.c | 6 +++++-
|
||||
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/sysprof-live-unwinder/tests/test-live-unwinder.c b/src/sysprof-live-unwinder/tests/test-live-unwinder.c
|
||||
index c3eda85a..a0dabeb3 100644
|
||||
--- a/src/sysprof-live-unwinder/tests/test-live-unwinder.c
|
||||
+++ b/src/sysprof-live-unwinder/tests/test-live-unwinder.c
|
||||
@@ -59,7 +59,11 @@
|
||||
#define SYSPROF_ARCH_PREFERRED_REGS DWARF_NEEDED_REGS
|
||||
/* TODO: add other architectures, imitating the linux tools/perf tree */
|
||||
#else
|
||||
-# define SYSPROF_ARCH_PREFERRED_REGS PERF_REG_EXTENDED_MASK
|
||||
+# ifdef PERF_REG_EXTENDED_MASK
|
||||
+# define SYSPROF_ARCH_PREFERRED_REGS PERF_REG_EXTENDED_MASK
|
||||
+# else
|
||||
+# define SYSPROF_ARCH_PREFERRED_REGS 0
|
||||
+# endif
|
||||
#endif /* _ASM_{arch}_PERF_REGS_H */
|
||||
|
||||
static gboolean sample_stack;
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,466 +0,0 @@
|
||||
%global glib2_version 2.67.4
|
||||
|
||||
Name: sysprof
|
||||
Version: 3.40.1
|
||||
Release: 3%{?dist}
|
||||
Summary: A system-wide Linux profiler
|
||||
|
||||
License: GPLv3+
|
||||
URL: http://www.sysprof.com
|
||||
Source0: https://download.gnome.org/sources/sysprof/3.40/sysprof-%{version}.tar.xz
|
||||
|
||||
BuildRequires: gcc
|
||||
BuildRequires: gcc-c++
|
||||
BuildRequires: gettext
|
||||
BuildRequires: itstool
|
||||
BuildRequires: meson
|
||||
BuildRequires: pkgconfig(gio-2.0) >= %{glib2_version}
|
||||
BuildRequires: pkgconfig(gio-unix-2.0) >= %{glib2_version}
|
||||
BuildRequires: pkgconfig(glib-2.0) >= %{glib2_version}
|
||||
BuildRequires: pkgconfig(gobject-2.0)
|
||||
BuildRequires: pkgconfig(gtk+-3.0)
|
||||
BuildRequires: pkgconfig(json-glib-1.0)
|
||||
BuildRequires: pkgconfig(libdazzle-1.0)
|
||||
BuildRequires: pkgconfig(libsystemd)
|
||||
BuildRequires: pkgconfig(polkit-gobject-1)
|
||||
BuildRequires: pkgconfig(systemd)
|
||||
BuildRequires: /usr/bin/appstream-util
|
||||
BuildRequires: /usr/bin/desktop-file-validate
|
||||
|
||||
Requires: glib2%{?_isa} >= %{glib2_version}
|
||||
Requires: hicolor-icon-theme
|
||||
Requires: %{name}-cli%{?_isa} = %{version}-%{release}
|
||||
Requires: libsysprof-ui%{?_isa} = %{version}-%{release}
|
||||
|
||||
%description
|
||||
Sysprof is a sampling CPU profiler for Linux that collects accurate,
|
||||
high-precision data and provides efficient access to the sampled
|
||||
calltrees.
|
||||
|
||||
|
||||
%package cli
|
||||
Summary: Sysprof command line utility
|
||||
# sysprofd needs turbostat
|
||||
Requires: kernel-tools
|
||||
Requires: libsysprof%{?_isa} = %{version}-%{release}
|
||||
|
||||
%description cli
|
||||
The %{name}-cli package contains the sysprof-cli command line utility.
|
||||
|
||||
|
||||
%package -n libsysprof
|
||||
Summary: Sysprof libraries
|
||||
|
||||
%description -n libsysprof
|
||||
The libsysprof package contains the Sysprof libraries.
|
||||
|
||||
|
||||
%package -n libsysprof-ui
|
||||
Summary: Sysprof UI library
|
||||
|
||||
%description -n libsysprof-ui
|
||||
The libsysprof-ui package contains the Sysprof UI library.
|
||||
|
||||
|
||||
%package capture-devel
|
||||
Summary: Development files for sysprof-capture static library
|
||||
License: BSD-2-Clause-Patent
|
||||
Provides: sysprof-capture-static = %{version}-%{release}
|
||||
# Split out in F34
|
||||
Conflicts: %{name}-devel < 3.39.94-1
|
||||
|
||||
%description capture-devel
|
||||
The %{name}-capture-devel package contains the sysprof-capture static library and header files.
|
||||
|
||||
|
||||
%package devel
|
||||
Summary: Development files for %{name}
|
||||
Requires: %{name}-capture-devel%{?_isa} = %{version}-%{release}
|
||||
Requires: libsysprof%{?_isa} = %{version}-%{release}
|
||||
Requires: libsysprof-ui%{?_isa} = %{version}-%{release}
|
||||
|
||||
%description devel
|
||||
The %{name}-devel package contains libraries and header files for
|
||||
developing applications that use %{name}.
|
||||
|
||||
|
||||
%prep
|
||||
%autosetup -p1
|
||||
|
||||
|
||||
%build
|
||||
%meson
|
||||
%meson_build
|
||||
|
||||
|
||||
%install
|
||||
%meson_install
|
||||
%find_lang %{name} --with-gnome
|
||||
|
||||
|
||||
%check
|
||||
appstream-util validate-relax --nonet %{buildroot}%{_datadir}/metainfo/*.appdata.xml
|
||||
desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop
|
||||
|
||||
|
||||
%files
|
||||
%license COPYING
|
||||
%doc NEWS README.md AUTHORS
|
||||
%{_bindir}/sysprof
|
||||
%{_datadir}/applications/org.gnome.Sysprof3.desktop
|
||||
%{_datadir}/glib-2.0/schemas/org.gnome.sysprof3.gschema.xml
|
||||
%{_datadir}/icons/hicolor/*/*/*
|
||||
%{_datadir}/metainfo/org.gnome.Sysprof3.appdata.xml
|
||||
%{_datadir}/mime/packages/sysprof-mime.xml
|
||||
|
||||
%files cli -f %{name}.lang
|
||||
%license COPYING
|
||||
%{_bindir}/sysprof-cli
|
||||
%{_libexecdir}/sysprofd
|
||||
%{_datadir}/dbus-1/system.d/org.gnome.Sysprof2.conf
|
||||
%{_datadir}/dbus-1/system.d/org.gnome.Sysprof3.conf
|
||||
%{_datadir}/dbus-1/system-services/org.gnome.Sysprof2.service
|
||||
%{_datadir}/dbus-1/system-services/org.gnome.Sysprof3.service
|
||||
%{_datadir}/polkit-1/actions/org.gnome.sysprof3.policy
|
||||
%{_unitdir}/sysprof2.service
|
||||
%{_unitdir}/sysprof3.service
|
||||
|
||||
%files -n libsysprof
|
||||
%license COPYING
|
||||
%{_libdir}/libsysprof-4.so
|
||||
%{_libdir}/libsysprof-memory-4.so
|
||||
%{_libdir}/libsysprof-speedtrack-4.so
|
||||
|
||||
%files -n libsysprof-ui
|
||||
%license COPYING
|
||||
%{_libdir}/libsysprof-ui-4.so
|
||||
|
||||
%files capture-devel
|
||||
%license src/libsysprof-capture/COPYING
|
||||
%dir %{_includedir}/sysprof-4
|
||||
%{_includedir}/sysprof-4/sysprof-address.h
|
||||
%{_includedir}/sysprof-4/sysprof-capture-condition.h
|
||||
%{_includedir}/sysprof-4/sysprof-capture-cursor.h
|
||||
%{_includedir}/sysprof-4/sysprof-capture.h
|
||||
%{_includedir}/sysprof-4/sysprof-capture-reader.h
|
||||
%{_includedir}/sysprof-4/sysprof-capture-types.h
|
||||
%{_includedir}/sysprof-4/sysprof-capture-writer.h
|
||||
%{_includedir}/sysprof-4/sysprof-clock.h
|
||||
%{_includedir}/sysprof-4/sysprof-collector.h
|
||||
%{_includedir}/sysprof-4/sysprof-macros.h
|
||||
%{_includedir}/sysprof-4/sysprof-platform.h
|
||||
%{_includedir}/sysprof-4/sysprof-version.h
|
||||
%{_includedir}/sysprof-4/sysprof-version-macros.h
|
||||
%{_libdir}/libsysprof-capture-4.a
|
||||
%{_libdir}/pkgconfig/sysprof-capture-4.pc
|
||||
|
||||
%files devel
|
||||
%{_includedir}/sysprof-4/
|
||||
%{_libdir}/pkgconfig/sysprof-4.pc
|
||||
%{_libdir}/pkgconfig/sysprof-ui-4.pc
|
||||
%{_datadir}/dbus-1/interfaces/org.gnome.Sysprof2.xml
|
||||
%{_datadir}/dbus-1/interfaces/org.gnome.Sysprof3.Profiler.xml
|
||||
%{_datadir}/dbus-1/interfaces/org.gnome.Sysprof3.Service.xml
|
||||
|
||||
|
||||
%changelog
|
||||
* Tue Aug 10 2021 Mohan Boddu <mboddu@redhat.com> - 3.40.1-3
|
||||
- Rebuilt for IMA sigs, glibc 2.34, aarch64 flags
|
||||
Related: rhbz#1991688
|
||||
|
||||
* Fri Apr 16 2021 Mohan Boddu <mboddu@redhat.com> - 3.40.1-2
|
||||
- Rebuilt for RHEL 9 BETA on Apr 15th 2021. Related: rhbz#1947937
|
||||
|
||||
* Tue Mar 23 2021 Kalev Lember <klember@redhat.com> - 3.40.1-1
|
||||
- Update to 3.40.1
|
||||
|
||||
* Mon Mar 22 2021 Kalev Lember <klember@redhat.com> - 3.40.0-1
|
||||
- Update to 3.40.0
|
||||
|
||||
* Tue Mar 16 2021 Kalev Lember <klember@redhat.com> - 3.39.94-2
|
||||
- Add explicit conflicts to help with upgrades
|
||||
|
||||
* Thu Feb 25 2021 Kalev Lember <klember@redhat.com> - 3.39.94-1
|
||||
- Update to 3.39.94
|
||||
|
||||
* Wed Feb 24 2021 Kalev Lember <klember@redhat.com> - 3.39.92-2
|
||||
- Split sysprof-capture library and header files out to sysprof-capture-devel
|
||||
- Update minimum required glib2 version
|
||||
|
||||
* Wed Feb 24 2021 Kalev Lember <klember@redhat.com> - 3.39.92-1
|
||||
- Update to 3.39.92
|
||||
|
||||
* Mon Feb 22 2021 Kalev Lember <klember@redhat.com> - 3.39.90-2
|
||||
- Specify pic for static libsysprof-capture
|
||||
|
||||
* Thu Feb 18 2021 Kalev Lember <klember@redhat.com> - 3.39.90-1
|
||||
- Update to 3.39.90
|
||||
|
||||
* Wed Jan 27 2021 Fedora Release Engineering <releng@fedoraproject.org> - 3.38.1-3
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild
|
||||
|
||||
* Tue Oct 20 2020 Kalev Lember <klember@redhat.com> - 3.38.1-2
|
||||
- Rebuild
|
||||
|
||||
* Fri Oct 16 2020 Kalev Lember <klember@redhat.com> - 3.38.1-1
|
||||
- Update to 3.38.1
|
||||
|
||||
* Sun Sep 20 2020 Kalev Lember <klember@redhat.com> - 3.38.0-2
|
||||
- Split out a separate libsysprof package and avoid -devel subpackage depending
|
||||
on the GUI app
|
||||
|
||||
* Sat Sep 12 2020 Kalev Lember <klember@redhat.com> - 3.38.0-1
|
||||
- Update to 3.38.0
|
||||
|
||||
* Mon Sep 07 2020 Kalev Lember <klember@redhat.com> - 3.37.92-1
|
||||
- Update to 3.37.92
|
||||
|
||||
* Mon Aug 17 2020 Kalev Lember <klember@redhat.com> - 3.37.90-1
|
||||
- Update to 3.37.90
|
||||
|
||||
* Wed Jul 29 2020 Fedora Release Engineering <releng@fedoraproject.org> - 3.36.0-2
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
|
||||
|
||||
* Sat Mar 07 2020 Kalev Lember <klember@redhat.com> - 3.36.0-1
|
||||
- Update to 3.36.0
|
||||
|
||||
* Mon Mar 02 2020 Kalev Lember <klember@redhat.com> - 3.35.92-1
|
||||
- Update to 3.35.92
|
||||
|
||||
* Fri Jan 31 2020 Fedora Release Engineering <releng@fedoraproject.org> - 3.35.3-2
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild
|
||||
|
||||
* Fri Jan 10 2020 Kalev Lember <klember@redhat.com> - 3.35.3-1
|
||||
- Update to 3.35.3
|
||||
|
||||
* Wed Dec 11 2019 Adam Williamson <awilliam@redhat.com> - 3.35.2-1
|
||||
- Update to 3.35.2
|
||||
|
||||
* Mon Oct 07 2019 Kalev Lember <klember@redhat.com> - 3.34.1-1
|
||||
- Update to 3.34.1
|
||||
|
||||
* Tue Sep 10 2019 Kalev Lember <klember@redhat.com> - 3.34.0-1
|
||||
- Update to 3.34.0
|
||||
|
||||
* Thu Sep 05 2019 Kalev Lember <klember@redhat.com> - 3.33.92-1
|
||||
- Update to 3.33.92
|
||||
- Set minimum required glib2 version
|
||||
|
||||
* Tue Aug 27 2019 Kalev Lember <klember@redhat.com> - 3.33.90-2
|
||||
- Add kernel-tools runtime dep for turbostat
|
||||
|
||||
* Mon Aug 26 2019 Kalev Lember <klember@redhat.com> - 3.33.90-1
|
||||
- Update to 3.33.90
|
||||
|
||||
* Sat Jul 27 2019 Fedora Release Engineering <releng@fedoraproject.org> - 3.33.3-2
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild
|
||||
|
||||
* Fri Jul 19 2019 Kalev Lember <klember@redhat.com> - 3.33.3-1
|
||||
- Update to 3.33.3
|
||||
|
||||
* Wed Mar 13 2019 Kalev Lember <klember@redhat.com> - 3.32.0-1
|
||||
- Update to 3.32.0
|
||||
|
||||
* Tue Feb 19 2019 Kalev Lember <klember@redhat.com> - 3.31.91-1
|
||||
- Update to 3.31.91
|
||||
|
||||
* Thu Feb 07 2019 Kalev Lember <klember@redhat.com> - 3.31.90-1
|
||||
- Update to 3.31.90
|
||||
|
||||
* Sun Feb 03 2019 Fedora Release Engineering <releng@fedoraproject.org> - 3.31.1-3
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild
|
||||
|
||||
* Thu Jan 10 2019 Kalev Lember <klember@redhat.com> - 3.31.1-2
|
||||
- Backport new API for gnome-builder
|
||||
|
||||
* Tue Oct 09 2018 Kalev Lember <klember@redhat.com> - 3.31.1-1
|
||||
- Update to 3.31.1
|
||||
|
||||
* Wed Sep 26 2018 Kalev Lember <klember@redhat.com> - 3.30.1-1
|
||||
- Update to 3.30.1
|
||||
|
||||
* Fri Sep 07 2018 Kalev Lember <klember@redhat.com> - 3.30.0-1
|
||||
- Update to 3.30.0
|
||||
- Drop ldconfig scriptlets
|
||||
|
||||
* Tue Jul 31 2018 Florian Weimer <fweimer@redhat.com> - 3.28.1-3
|
||||
- Rebuild with fixed binutils
|
||||
|
||||
* Sat Jul 14 2018 Fedora Release Engineering <releng@fedoraproject.org> - 3.28.1-2
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild
|
||||
|
||||
* Tue Apr 10 2018 Kalev Lember <klember@redhat.com> - 3.28.1-1
|
||||
- Update to 3.28.1
|
||||
|
||||
* Wed Mar 14 2018 Kalev Lember <klember@redhat.com> - 3.28.0-1
|
||||
- Update to 3.28.0
|
||||
|
||||
* Mon Mar 05 2018 Kalev Lember <klember@redhat.com> - 3.27.92-1
|
||||
- Update to 3.27.92
|
||||
|
||||
* Sat Mar 03 2018 Kalev Lember <klember@redhat.com> - 3.27.91-1
|
||||
- Update to 3.27.91
|
||||
- Switch to the meson build system
|
||||
|
||||
* Fri Feb 09 2018 Fedora Release Engineering <releng@fedoraproject.org> - 3.26.1-4
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild
|
||||
|
||||
* Sat Feb 03 2018 Igor Gnatenko <ignatenkobrain@fedoraproject.org> - 3.26.1-3
|
||||
- Switch to %%ldconfig_scriptlets
|
||||
|
||||
* Fri Jan 05 2018 Igor Gnatenko <ignatenkobrain@fedoraproject.org> - 3.26.1-2
|
||||
- Remove obsolete scriptlets
|
||||
|
||||
* Sun Oct 08 2017 Kalev Lember <klember@redhat.com> - 3.26.1-1
|
||||
- Update to 3.26.1
|
||||
|
||||
* Sat Sep 16 2017 Kalev Lember <klember@redhat.com> - 3.26.0-1
|
||||
- Update to 3.26.0
|
||||
|
||||
* Thu Sep 07 2017 Kalev Lember <klember@redhat.com> - 3.25.92-1
|
||||
- Update to 3.25.92
|
||||
|
||||
* Thu Aug 03 2017 Fedora Release Engineering <releng@fedoraproject.org> - 3.24.1-3
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild
|
||||
|
||||
* Thu Jul 27 2017 Fedora Release Engineering <releng@fedoraproject.org> - 3.24.1-2
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild
|
||||
|
||||
* Tue Apr 11 2017 Kalev Lember <klember@redhat.com> - 3.24.1-1
|
||||
- Update to 3.24.1
|
||||
|
||||
* Mon Mar 20 2017 Kalev Lember <klember@redhat.com> - 3.24.0-1
|
||||
- Update to 3.24.0
|
||||
|
||||
* Thu Mar 16 2017 Kalev Lember <klember@redhat.com> - 3.23.92-1
|
||||
- Update to 3.23.92
|
||||
|
||||
* Wed Mar 01 2017 Kalev Lember <klember@redhat.com> - 3.23.91-1
|
||||
- Update to 3.23.91
|
||||
- Add appdata validation
|
||||
|
||||
* Sat Feb 11 2017 Fedora Release Engineering <releng@fedoraproject.org> - 3.22.3-2
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild
|
||||
|
||||
* Tue Nov 29 2016 Kalev Lember <klember@redhat.com> - 3.22.3-1
|
||||
- Update to 3.22.3
|
||||
|
||||
* Wed Nov 02 2016 Kalev Lember <klember@redhat.com> - 3.22.2-1
|
||||
- Update to 3.22.2
|
||||
|
||||
* Wed Oct 12 2016 Kalev Lember <klember@redhat.com> - 3.22.1-1
|
||||
- Update to 3.22.1
|
||||
- Don't use -Werror for builds
|
||||
|
||||
* Wed Sep 21 2016 Kalev Lember <klember@redhat.com> - 3.22.0-2
|
||||
- Split out sysprof-cli and libsysprof-ui subpackages
|
||||
|
||||
* Wed Sep 21 2016 Kalev Lember <klember@redhat.com> - 3.22.0-1
|
||||
- Update to 3.22.0
|
||||
|
||||
* Mon Sep 5 2016 Peter Robinson <pbrobinson@fedoraproject.org> 3.21.91-2
|
||||
- Build on all arches now generic atomics supported
|
||||
|
||||
* Fri Sep 02 2016 Kalev Lember <klember@redhat.com> - 3.21.91-1
|
||||
- Update to 3.21.91
|
||||
|
||||
* Tue Aug 23 2016 Kalev Lember <klember@redhat.com> - 3.21.90-2
|
||||
- Enable building for arm architectures
|
||||
|
||||
* Tue Aug 23 2016 Kalev Lember <klember@redhat.com> - 3.21.90-1
|
||||
- Update to 3.21.90
|
||||
|
||||
* Mon Aug 08 2016 Kalev Lember <klember@redhat.com> - 3.20.0-1
|
||||
- Update to 3.20.0
|
||||
- Modernize spec file
|
||||
|
||||
* Fri Feb 05 2016 Fedora Release Engineering <releng@fedoraproject.org> - 1.2.0-8
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild
|
||||
|
||||
* Fri Jun 19 2015 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.2.0-7
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild
|
||||
|
||||
* Mon Aug 18 2014 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.2.0-6
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild
|
||||
|
||||
* Sun Jun 08 2014 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.2.0-5
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild
|
||||
|
||||
* Sun Aug 04 2013 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.2.0-4
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild
|
||||
|
||||
* Fri Jun 28 2013 Gianluca Sforna <giallu@gmail.com> 1.2.0-3
|
||||
- fix udev rule path (#979545)
|
||||
|
||||
* Fri Feb 15 2013 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.2.0-2
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild
|
||||
|
||||
* Sat Sep 15 2012 Gianluca Sforna <giallu@gmail.com> 1.2.0-1
|
||||
- New upstream release
|
||||
|
||||
* Sat Jul 21 2012 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.1.8-4
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild
|
||||
|
||||
* Sat Jan 14 2012 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.1.8-3
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild
|
||||
|
||||
* Mon Nov 07 2011 Adam Jackson <ajax@redhat.com> 1.1.8-2
|
||||
- Rebuild to break bogus libpng dependency
|
||||
|
||||
* Thu Jul 28 2011 Gianluca Sforna <giallu@gmail.com> 1.1.8-1
|
||||
- New upstream release
|
||||
|
||||
* Fri Jun 24 2011 Gianluca Sforna <giallu@gmail.com> 1.1.6-3
|
||||
- Fix missing icon (#558089)
|
||||
|
||||
* Wed Feb 09 2011 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.1.6-2
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild
|
||||
|
||||
* Tue Jun 8 2010 Gianluca Sforna <giallu gmail com> - 1.1.6-1
|
||||
- New upstream release
|
||||
|
||||
* Sun Sep 27 2009 Gianluca Sforna <giallu gmail com> - 1.1.2-3
|
||||
- Incorporate suggestions from package review
|
||||
- Require kernel 2.6.31
|
||||
- Updated description
|
||||
|
||||
* Sat Sep 26 2009 Gianluca Sforna <giallu gmail com> - 1.1.2-1
|
||||
- New upstream release
|
||||
|
||||
* Wed Apr 9 2008 Gianluca Sforna <giallu gmail com> - 1.0.9-1
|
||||
- version update to 1.0.9
|
||||
|
||||
* Tue Aug 28 2007 Gianluca Sforna <giallu gmail com> 1.0.8-2
|
||||
- update License field
|
||||
|
||||
* Thu Dec 21 2006 Gianluca Sforna <giallu gmail com> 1.0.8-1
|
||||
- version update to 1.0.8
|
||||
|
||||
* Tue Nov 21 2006 Gianluca Sforna <giallu gmail com> 1.0.7-1
|
||||
- version update to 1.0.7
|
||||
|
||||
* Wed Nov 1 2006 Gianluca Sforna <giallu gmail com> 1.0.5-1
|
||||
- version update
|
||||
|
||||
* Sun Oct 8 2006 Gianluca Sforna <giallu gmail com> 1.0.3-6
|
||||
- better to use ExclusiveArch %%{ix86} (thanks Ville)
|
||||
|
||||
* Thu Oct 5 2006 Gianluca Sforna <giallu gmail com> 1.0.3-5
|
||||
- add ExclusiveArch to match sysprof-kmod supported archs
|
||||
|
||||
* Mon Oct 2 2006 Gianluca Sforna <giallu gmail com> 1.0.3-4
|
||||
- add .desktop file
|
||||
|
||||
* Sat Sep 30 2006 Gianluca Sforna <giallu gmail com> 1.0.3-3
|
||||
- versioned Provides
|
||||
- add BR: binutils-devel
|
||||
|
||||
* Fri Sep 29 2006 Gianluca Sforna <giallu gmail com> 1.0.3-2
|
||||
- own sysprof directory
|
||||
|
||||
* Thu Jun 22 2006 Gianluca Sforna <giallu gmail com> 1.0.3-1
|
||||
- version update
|
||||
- use standard %%configure macro
|
||||
|
||||
* Sun May 14 2006 Gianluca Sforna <giallu gmail com> 1.0.2-1
|
||||
- Initial Version
|
6
gating.yaml
Normal file
6
gating.yaml
Normal file
@ -0,0 +1,6 @@
|
||||
--- !Policy
|
||||
product_versions:
|
||||
- rhel-10
|
||||
decision_context: osci_compose_gate
|
||||
rules:
|
||||
- !PassingTestCaseRule {test_case_name: desktop-qe.desktop-ci.tier1-gating.functional}
|
2
sources
Normal file
2
sources
Normal file
@ -0,0 +1,2 @@
|
||||
SHA512 (sysprof-47.1.tar.xz) = 9f8db2169c761109f27fe45f805f863b6f15f35cc7ad8ccaf68f047446dc8552c27a340442a1466f719b588045573f9a9c0e4fa1ea15f33f12074ca64a074e7c
|
||||
SHA512 (libunwind-1.8.1.tar.gz) = aba7b578c1b8cbe78f05b64e154f3530525f8a34668b2a9f1ee6acb4b22c857befe34ad4e9e8cca99dbb66689d41bc72060a8f191bd8be232725d342809431b3
|
254
sysprof.spec
Normal file
254
sysprof.spec
Normal file
@ -0,0 +1,254 @@
|
||||
%global glib2_version 2.76.0
|
||||
%global tarball_version %%(echo %{version} | tr '~' '.')
|
||||
%global bundled_libunwind %{defined rhel}
|
||||
|
||||
%if 0%{?bundled_libunwind}
|
||||
%global libunwind_version 1.8.1
|
||||
%global _legacy_common_support 1
|
||||
%endif
|
||||
|
||||
Name: sysprof
|
||||
Version: 47.1
|
||||
Release: %autorelease
|
||||
Summary: A system-wide Linux profiler
|
||||
|
||||
License: GPL-2.0-or-later AND GPL-3.0-or-later AND CC-BY-SA-4.0 AND BSD-2-Clause-Patent
|
||||
URL: http://www.sysprof.com
|
||||
Source0: https://download.gnome.org/sources/sysprof/47/sysprof-%{tarball_version}.tar.xz
|
||||
%if 0%{?bundled_libunwind}
|
||||
Source1: https://github.com/libunwind/libunwind/releases/download/v%{libunwind_version}/libunwind-%{libunwind_version}.tar.gz
|
||||
%endif
|
||||
|
||||
# Backports of debuginfod and sysprof-live-unwinder from GNOME 48
|
||||
Patch: 0001-build-add-47-version-macros.patch
|
||||
Patch: 0002-libsysprof-elf-do-not-allow-setting-self-as-debug-li.patch
|
||||
Patch: 0003-libsysprof-elf-do-not-generate-fallback-names.patch
|
||||
Patch: 0004-sysprof-update-to-AdwSpinner.patch
|
||||
Patch: 0005-sysprof-add-SysprofDocumentTask-abstraction.patch
|
||||
Patch: 0006-libsysprof-add-setup-hooks-for-symbolizers.patch
|
||||
Patch: 0007-libsysprof-hoist-fallback-symbol-creation.patch
|
||||
Patch: 0008-libsysprof-add-debuginfod-symbolizer.patch
|
||||
Patch: 0009-libsysprof-ensure-access-to-process-info.patch
|
||||
Patch: 0010-libsysprof-fix-building-with-Ddebuginfod-auto.patch
|
||||
Patch: 0011-libsysprof-return-NULL-instance-unless-debuginfod-wo.patch
|
||||
Patch: 0012-build-always-build-debuginfod-symbolizer.patch
|
||||
Patch: 0013-libsysprof-remove-unnecessary-address-calculation.patch
|
||||
Patch: 0014-libsysprof-add-muxer-GSource.patch
|
||||
Patch: 0015-libsysprof-add-support-for-stack-regs-options-in-att.patch
|
||||
Patch: 0016-sysprofd-add-support-for-unwinding-without-frame-poi.patch
|
||||
Patch: 0017-libsysprof-add-SysprofUserSampler-for-live-unwinding.patch
|
||||
Patch: 0018-sysprof-cli-add-support-for-live-unwinding.patch
|
||||
Patch: 0019-sysprof-add-UI-for-live-unwinding.patch
|
||||
Patch: 0020-sysprof-live-unwinder-ifdef-unused-code-off-x86.patch
|
||||
Patch: 0021-sysprof-only-show-user-stack-sampling-on-x86.patch
|
||||
Patch: 0022-libsysprof-check-for-PERF_REG_EXTENDED_MASK-availabi.patch
|
||||
Patch: 0023-sysprof-live-unwinder-fix-source-func-prototype.patch
|
||||
Patch: 0024-sysprof-live-unwinder-handle-large-stack-unwind-size.patch
|
||||
Patch: 0025-unwinder-wait-for-completion-of-subprocess.patch
|
||||
Patch: 0026-sysprof-user-sampler-implement-await-for-FDs.patch
|
||||
Patch: 0027-libsysprof-provide-unwind-pipe-from-client.patch
|
||||
Patch: 0028-sysprof-live-unwinder-error-out-on-capture-failure.patch
|
||||
Patch: 0029-sysprofd-remove-unused-code.patch
|
||||
Patch: 0030-build-lower-libpanel-requirement-to-ease-some-build-.patch
|
||||
Patch: 0031-build-allow-await-for-FD-with-older-libdex.patch
|
||||
Patch: 0032-sysprof-default-stack-capturing-as-enabled.patch
|
||||
Patch: 0033-tests-fix-test-on-s390.patch
|
||||
|
||||
BuildRequires: gcc
|
||||
BuildRequires: gcc-c++
|
||||
BuildRequires: gettext
|
||||
BuildRequires: itstool
|
||||
BuildRequires: meson
|
||||
BuildRequires: pkgconfig(gio-2.0) >= %{glib2_version}
|
||||
BuildRequires: pkgconfig(gio-unix-2.0) >= %{glib2_version}
|
||||
BuildRequires: pkgconfig(glib-2.0) >= %{glib2_version}
|
||||
BuildRequires: pkgconfig(gobject-2.0)
|
||||
BuildRequires: pkgconfig(gtk4)
|
||||
BuildRequires: pkgconfig(json-glib-1.0)
|
||||
BuildRequires: pkgconfig(libadwaita-1)
|
||||
BuildRequires: pkgconfig(libdex-1)
|
||||
BuildRequires: pkgconfig(libpanel-1)
|
||||
BuildRequires: pkgconfig(libsystemd)
|
||||
BuildRequires: pkgconfig(polkit-gobject-1)
|
||||
BuildRequires: pkgconfig(systemd)
|
||||
BuildRequires: pkgconfig(libdw)
|
||||
BuildRequires: pkgconfig(libdebuginfod)
|
||||
BuildRequires: /usr/bin/appstream-util
|
||||
BuildRequires: /usr/bin/desktop-file-validate
|
||||
|
||||
%if 0%{?bundled_libunwind}
|
||||
BuildRequires: automake libtool autoconf make
|
||||
%else
|
||||
BuildRequires: pkgconfig(libunwind-generic)
|
||||
%endif
|
||||
|
||||
Requires: glib2%{?_isa} >= %{glib2_version}
|
||||
Requires: hicolor-icon-theme
|
||||
Requires: %{name}-cli%{?_isa} = %{version}-%{release}
|
||||
|
||||
%description
|
||||
Sysprof is a sampling CPU profiler for Linux that collects accurate,
|
||||
high-precision data and provides efficient access to the sampled
|
||||
calltrees.
|
||||
|
||||
|
||||
%package agent
|
||||
Summary: Sysprof agent utility
|
||||
|
||||
%description agent
|
||||
The %{name}-agent package contains the sysprof-agent program. It provides a P2P
|
||||
D-Bus API to the process which can control subprocesses. It's used by IDE
|
||||
tooling to have more control across container boundaries.
|
||||
|
||||
|
||||
%package cli
|
||||
Summary: Sysprof command line utility
|
||||
# sysprofd needs turbostat
|
||||
Requires: kernel-tools
|
||||
Requires: libsysprof%{?_isa} = %{version}-%{release}
|
||||
|
||||
%description cli
|
||||
The %{name}-cli package contains the sysprof-cli command line utility.
|
||||
|
||||
|
||||
%package -n libsysprof
|
||||
Summary: Sysprof libraries
|
||||
# Subpackage removed/obsoleted in F39
|
||||
Obsoletes: libsysprof-ui < 45.0
|
||||
%if 0%{?bundled_libunwind}
|
||||
Provides: bundled(libunwind) = %{libunwind_version}
|
||||
%endif
|
||||
|
||||
%description -n libsysprof
|
||||
The libsysprof package contains the Sysprof libraries.
|
||||
|
||||
|
||||
%package capture-devel
|
||||
Summary: Development files for sysprof-capture static library
|
||||
License: BSD-2-Clause-Patent
|
||||
Provides: sysprof-capture-static = %{version}-%{release}
|
||||
|
||||
%description capture-devel
|
||||
The %{name}-capture-devel package contains the sysprof-capture static library and header files.
|
||||
|
||||
|
||||
%package devel
|
||||
Summary: Development files for %{name}
|
||||
Requires: %{name}-capture-devel%{?_isa} = %{version}-%{release}
|
||||
Requires: libsysprof%{?_isa} = %{version}-%{release}
|
||||
|
||||
%description devel
|
||||
The %{name}-devel package contains libraries and header files for
|
||||
developing applications that use %{name}.
|
||||
|
||||
|
||||
%prep
|
||||
%if 0%{?bundled_libunwind}
|
||||
%setup -b 1 -n libunwind-%{libunwind_version}
|
||||
%endif
|
||||
%setup -n sysprof-%{tarball_version}
|
||||
%autopatch -p1
|
||||
|
||||
|
||||
%build
|
||||
%if 0%{?bundled_libunwind}
|
||||
# First build private libunwind
|
||||
%global libunwind_install_dir %{buildroot}%{_builddir}/libunwind
|
||||
pushd ../libunwind-%{libunwind_version}
|
||||
mkdir -p %{_builddir}/libunwind/
|
||||
aclocal
|
||||
libtoolize --force
|
||||
autoheader
|
||||
automake --add-missing
|
||||
autoconf
|
||||
%configure --enable-static --disable-shared --enable-setjmp=no --disable-debug --disable-documentation --disable-ptrace --disable-coredump --disable-minidebuginfo --disable-zlibdebuginfo --with-pic
|
||||
make %{?_smp_mflags} install DESTDIR=%{libunwind_install_dir}
|
||||
popd
|
||||
# Our "/usr" install to DESTDIR wont get picked up by the
|
||||
# pkgconfig use in meson so ensure access to those include
|
||||
# and linker directories manually.
|
||||
export CFLAGS="$CFLAGS -I%{libunwind_install_dir}/usr/include"
|
||||
export LDFLAGS="$LDFLAGS -L%{libunwind_install_dir}/usr/%{_lib}"
|
||||
%global pkg_config_path_override --pkg-config-path %{libunwind_install_dir}/usr/%{_lib}/pkgconfig
|
||||
%endif
|
||||
|
||||
# Now build sysprof
|
||||
%meson %{?pkg_config_path_override}
|
||||
%meson_build
|
||||
|
||||
|
||||
%install
|
||||
%meson_install
|
||||
%find_lang %{name} --with-gnome
|
||||
%if 0%{?bundled_libunwind}
|
||||
# Appease checks which would include buildroot paths for the
|
||||
# libunwind-generic.a linked in.
|
||||
strip -s %{buildroot}/usr/%{_lib}/libsysprof-*.so
|
||||
%endif
|
||||
|
||||
|
||||
%check
|
||||
appstream-util validate-relax --nonet %{buildroot}%{_datadir}/metainfo/*.appdata.xml
|
||||
desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop
|
||||
|
||||
|
||||
%files
|
||||
%license COPYING
|
||||
%doc NEWS README.md AUTHORS
|
||||
%{_bindir}/sysprof
|
||||
%{_datadir}/applications/org.gnome.Sysprof.desktop
|
||||
%{_datadir}/icons/hicolor/*/*/*
|
||||
%{_datadir}/metainfo/org.gnome.Sysprof.appdata.xml
|
||||
%{_datadir}/mime/packages/sysprof-mime.xml
|
||||
|
||||
%files agent
|
||||
%license COPYING
|
||||
%{_bindir}/sysprof-agent
|
||||
|
||||
%files cli -f %{name}.lang
|
||||
%license COPYING
|
||||
%{_bindir}/sysprof-cli
|
||||
%{_libexecdir}/sysprofd
|
||||
%{_libexecdir}/sysprof-live-unwinder
|
||||
%{_datadir}/dbus-1/system.d/org.gnome.Sysprof3.conf
|
||||
%{_datadir}/dbus-1/system-services/org.gnome.Sysprof3.service
|
||||
%{_datadir}/polkit-1/actions/org.gnome.sysprof3.policy
|
||||
%{_unitdir}/sysprof3.service
|
||||
|
||||
%files -n libsysprof
|
||||
%license COPYING COPYING.gpl-2
|
||||
%{_libdir}/libsysprof-6.so.6*
|
||||
%{_libdir}/libsysprof-memory-6.so
|
||||
%{_libdir}/libsysprof-speedtrack-6.so
|
||||
%{_libdir}/libsysprof-tracer-6.so
|
||||
|
||||
%files capture-devel
|
||||
%license src/libsysprof-capture/COPYING
|
||||
%dir %{_includedir}/sysprof-6
|
||||
%{_includedir}/sysprof-6/sysprof-address.h
|
||||
%{_includedir}/sysprof-6/sysprof-capture-condition.h
|
||||
%{_includedir}/sysprof-6/sysprof-capture-cursor.h
|
||||
%{_includedir}/sysprof-6/sysprof-capture.h
|
||||
%{_includedir}/sysprof-6/sysprof-capture-reader.h
|
||||
%{_includedir}/sysprof-6/sysprof-capture-types.h
|
||||
%{_includedir}/sysprof-6/sysprof-capture-writer.h
|
||||
%{_includedir}/sysprof-6/sysprof-clock.h
|
||||
%{_includedir}/sysprof-6/sysprof-collector.h
|
||||
%{_includedir}/sysprof-6/sysprof-macros.h
|
||||
%{_includedir}/sysprof-6/sysprof-platform.h
|
||||
%{_includedir}/sysprof-6/sysprof-version.h
|
||||
%{_includedir}/sysprof-6/sysprof-version-macros.h
|
||||
%{_libdir}/libsysprof-capture-4.a
|
||||
%{_libdir}/pkgconfig/sysprof-capture-4.pc
|
||||
|
||||
%files devel
|
||||
%{_includedir}/sysprof-6/
|
||||
%{_libdir}/libsysprof-6.so
|
||||
%{_libdir}/pkgconfig/sysprof-6.pc
|
||||
%{_datadir}/dbus-1/interfaces/org.gnome.Sysprof.Agent.xml
|
||||
%{_datadir}/dbus-1/interfaces/org.gnome.Sysprof3.Profiler.xml
|
||||
%{_datadir}/dbus-1/interfaces/org.gnome.Sysprof3.Service.xml
|
||||
|
||||
|
||||
%changelog
|
||||
%autochangelog
|
Loading…
Reference in New Issue
Block a user