sysprofd: add support for unwinding without frame pointers

This provides a new sysprof-live-unwinder subprocess that runs as root to
allow accessing all processes on the system via /proc/$pid/. It is spawned
by sysprofd with various perf event FDs and a FD to write captures to.

Ideally the capture_fd is something that will naturally error if the client
application crashes (such as a socketpair() having the peer close). This
is not enforced but encouraged. Additionally, an event_fd is used to allow
the client application to signal the live-unwinder to exit.

Unwinding is performed by looking at the modules loaded into the target
pid and using libdwfl to access DWARF/CFI/etc state machinery. Stack data
does not touch the disk as it exists in a mmap buffer from perf and is
then translated into a callchain and sent to the Sysprof client.

Unwinding occurs as normal post-mortem though is improved through the use
of debuginfod to locate the appropriate symbols.
This commit is contained in:
Christian Hergert
2024-11-03 10:41:44 -08:00
parent 39b96f47f5
commit 1bd79af439
15 changed files with 2580 additions and 4 deletions

View File

@ -0,0 +1,23 @@
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
<interface name="org.gnome.Sysprof3.Unwinder">
<!--
Unwind:
@stack_size: the size of stacks that are sampled
@perf_fds: an array of (perf_fd, CPU number)
@event_fd: an event fd to write to for notifying unwinder should exit
@capture_fd: (out): a FD that will be written to containing samples
Unwinding will stop when capture_fd can no longer be written to
such as being closed by the consumer of this API.
-->
<method name="Unwind">
<annotation name="org.gtk.GDBus.C.UnixFD" value="true"/>
<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"/>
</method>
</interface>
</node>