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,35 @@
sysprof_live_unwinder_test_env = [
'G_DEBUG=gc-friendly',
'GSETTINGS_BACKEND=memory',
'MALLOC_CHECK_=2',
]
sysprof_live_unwinder_testsuite_c_args = [
'-DG_ENABLE_DEBUG',
'-UG_DISABLE_ASSERT',
'-UG_DISABLE_CAST_CHECKS',
'-DBUILDDIR="@0@"'.format(meson.current_build_dir()),
]
sysprof_live_unwinder_testsuite = {
'test-live-unwinder' : {'skip': true},
}
sysprof_live_unwinder_testsuite_deps = [
libsysprof_static_dep,
]
if polkit_agent_dep.found()
sysprof_live_unwinder_testsuite_deps += polkit_agent_dep
endif
foreach test, params: sysprof_live_unwinder_testsuite
test_exe = executable(test, '@0@.c'.format(test),
c_args: sysprof_live_unwinder_testsuite_c_args,
dependencies: sysprof_live_unwinder_testsuite_deps,
)
if not params.get('skip', false)
test(test, test_exe, env: sysprof_live_unwinder_test_env)
endif
endforeach