This starts porting the old perf code from libsysprof into
libsysprof-profile. It does not bring over tracepoints yet, because we
need to think about how we want to support that. I may opt to do that as
a separate instrument even if that takes an additional perf fd.
This is a bit different than how we did things previously, but the same
mechanics are involved. Instead of multiple CPU registered together, we'll
just use one-stream-per-cpu.
Partly because I intend to drop support for profiling a single process as
that doesn't really get used much nor does it seem to yield very good
results from perf.
We can use the new infinite future here to mimic running forever when there
is no spawnable. Otherwise, if the spawnable exits we want to break out
of the recording loop.
I'd like to stop using tracefd, but since we need to maintain compatability
with older tooling, lets at least make it more ergonomic than adding an
instrument(s) for it.
The goal here is to do the whole thing on a fiber rather than how we were
doing it before. This just gets the counter registration going, but we
need to follow up with the parsing/lseek/etc code.
We want to reduce the chances we miss things between prepare and record
virtual methods, so delay the adding of processes until the recording is
started. We may get duplicate records, but we can deal with that when
analyzing the capture.
We might have the file data from the peer and can specify the data in the
capture writer directly.
It may be useful to allow compressing these too, but we can deal with that
at a later time.
If we need access to a privileged file in /proc or /sys we need to get
that through sysprofd. This implements basic checking of paths to see
if we need to get a /proc file from there.
We can't use the GetProfFD variant because that may still cause errors
when reading back due to how selinux and other LSMs may restrict read()
to get kallsyms.
This requires recent API additions in libdex.
If we are trying to get the file bytes and they are compressed, we may need
to transparently decompress those bytes. That way if the API requested
"/proc/cpuinfo" but really got "/proc/cpuinfo.gz" it still gets the same
bytes to consume.
If we want /proc/kallsyms and we discover /proc/kallsyms.gz, then use the
/proc/kallsyms.gz instead and transparently decompress it. Also, list the
file in sysprof_document_list_files() as /proc/kallsyms instead of
/proc/kallsyms.gz as that is really the intention (but mark the compressed
bit for decoding the chunks).