Serhei Makarov [Tue, 26 May 2020 16:08:40 +0000 (12:08 -0400)]
bigmap1.stp: tetentative fix for a hang on RHEL8
My suspicion is that the vfs_read probe was not triggering sufficiently often,
causing the script to keep running (and the subsequent attempt to kill it failed).
Added an extra probe within the testcase to time out after a while.
If it doesn't work, the in-testcase timeout should be further reduced.
XXX The failure to kill the process needs further investigation. It
was possible at one point to get a hang like this in the userspace
interpreter, but I'm unsure of the reason it's happening here and now.
Frank Ch. Eigler [Mon, 25 May 2020 11:23:26 +0000 (07:23 -0400)]
PR11599: fix buildid function & mark probes for stap list/run purposes
Listing mode and sdt derived probes muck with the understanding of the
new buildid probe points, since the process("....") argument string is
internally sometimes an exemplar executable name, and sometimes just
the buildid. (Too bad it's not easy to track what is what -- and we
even have code like dwarf_query::mount_well_formed_probe_point which
temporarily rewrites previously hand-crafted probe point arguments.)
This current set of changes seems to be the minimum to make all these
work & retain the buildid hexcode:
Frank Ch. Eigler [Sun, 24 May 2020 20:48:47 +0000 (16:48 -0400)]
PR11599: tweak macro for F31
runtime/linux/stp_tracepoint.h's fallback definition of
STAPCONF_TRACEPOINT_HAS_DATA needs to match the stapconf-generated
one - now they both define explicitly as 1, so they don't evoke
conflicting macro setting errors.
Aaron Merey [Sat, 23 May 2020 02:43:42 +0000 (22:43 -0400)]
util.cxx: Add function is_build_id()
Determines whether a string is a build-id. For the purposes of
this function, a string is considered a build-id when it consists
only of lowercase hex digits and has a length greater than 2.
Serhei Makarov [Fri, 22 May 2020 15:31:40 +0000 (11:31 -0400)]
PR11599: update STAPCONF_TRACEPOINT_HAS_DATA to work with kernel 5.7.0+
Until 2.6.35 (commit 38516ab59fbc5b), register_trace_* took one argument.
Until 5.7.0 (commit a2806ef77ff9a9), this could be checked by checking
for the absence of DECLARE_TRACE_NOARGS. Now _NOARGS variant is
removed, and we need to add an autoconf program to check the
register_trace_* function directly.
Aaron Merey [Thu, 14 May 2020 22:47:58 +0000 (18:47 -0400)]
PR25568: Add buildid-based process probes
Specify the targets of process probes using the build-id
of the target executable: 'probe process("BUILDID").*'.
BUILDID should be prefixed with '0x' to distinguish it
from a filename.
To find an executable with BUILDID stap will check
/usr/lib/.build-id. If the file cannot be found and
debuginfod is enabled, stap will also query debuginfod
for the executable.
Serhei Makarov [Tue, 19 May 2020 15:25:51 +0000 (11:25 -0400)]
PR10280 fix prev commit: UTS_RELEASE is vacuous, UTS_VERSION is not
The comparison of UTS_RELEASE vs session->kernel_release used two
compile-time values and not the values in the running kernel for both
sides of the comparison. Hence vacuous.
Now disabled by default, can be re-enabled with STP_FULL_VERREL_CHECK.
Previously enabled, could be disabled with STP_NO_VERREL_CHECK.
UTS_VERSION vs utsname()->version is still compared, where available.
Still enabled, can be disabled with STP_NO_VERREL_CHECK.
The comparisons of UTS_VERSION vs utsname()->version used compile-time
values and not the values in the running kernel for both sides of the
comparison. Hence vacuous.
Now disabled by default, can be re-enabled with STP_ENABLE_VERREL_CHECK.
Were previously enabled, could be disabled with STP_NO_VERREL_CHECK.
Serhei Makarov [Wed, 16 Jan 2019 18:56:23 +0000 (13:56 -0500)]
PR10280: re-enable 'force vermagic for guru-mode scripts'
Current version checking based on kernel ABI and build-ids is not
strict enough to prevent launching a stap module on a kernel version
it wasn't compiled for. This has the potential to crash a running
kernel, since ABI compatibility may not give a sufficient guarantee of
real compatibility.
This patch was reported to cause problems on a PPC machine, but the
reasons are still unclear. Worksforme with the PPC machine I tested it on,
but there are kernel patches that suggest the vermagic string may be
additionally mangled (43e24e83f35).
Re-enabling this and will cautiously monitor the aftermath.
Frank Ch. Eigler [Wed, 13 May 2020 00:06:18 +0000 (20:06 -0400)]
PR25579: look for new /sys/kernel/security/lockdown for mod-signing
Extend systemtap_session::modules_must_be_signed to look for activated
integrity or confidentiality mode to activate secureboot-related
module-signing logic.
Frank Ch. Eigler [Sun, 10 May 2020 19:15:33 +0000 (15:15 -0400)]
PR25841: python2+3 exploitation
Reworking aspects of the python tapset & translator logic to make it
work again, after an extended period away from the plantation. This
involved several bits:
Let all the the python[23].stp tapset functions use @cast()s that
extract debuginfo from the invoking HelperSDT.so file, not from some
always-obsolete list of libpython.so file names. This was enabled by
the per-probe-point cloning features pulled in recent commits. This
requires the _HelperSDT.c file to include the DWARF data normally
pulled from libpython, which is easy ... except for a few libpython3.7
internal data structures related to dicts. Those few decls are
copy-and-pasted (eww). python 3.6 support will need tweaks.
The python_{print,sprint} backtrace() functions are now provided
directly by the python[23].stp tapsets, as overloaded functions. They
determine the eligibility by testing $$$$provider against "HelperSDT2"
or "HelperSDT3" to identify the python version in effect in the
invoking python extension .so. The $$$$FOOBAR syntax is an
undocumented (sssh!) escape hatch for tapset functions invoked from
python*.module* probes which, to bypass one round of python $context
var expansion, and to land in the second round of sys/sdt.h $context
var expansion.
This relies on dead_control_remover being run eagerly & early during
symbol resolution, just as const folding, to eliminate unreachable
code. (Letting python3 HelperSDT.so functions try to resolve python2
data types would fail during pass 2.)
The generated procfs("_stp_python*_probes") {} probes now have a dummy
exit() body, so that probe-with-empty-body elision added in 2019 keeps
them.
Recent new code in tapsets.cxx used the "new"
for (auto x : CONTAINER) { }
construct, which some of our older rhel6 era c++ compilers can't grok.
So for now, uglify the code.
PR25841: support context vars in functions called from process.mark probes
Extending the prior work to <sys/sdt.h> markers. This is tricky
because the sdt derived_probes are built with a sequence of
intermediate copies and an ultimate transform to a process.statement
probe. So the function-cloning & .mark() context-var replacement is
done early, before the synthetic process.statement builder gets a kick
at cloning/etc. (And the latter doesn't know about sdt $$provider
etc.)
The oddest change is to deep_copy_visitor::visit_functioncall() which
used to clear the copy's referents[] array, but now we preserve (for
reasons elaborated upon in comments). This has the potential to
impact all the other probes, but initial testing shows nothing
adverse. No idea why we didn't do this earlier.
Nuked the unused sdt_query::convert_probe() function, not used since
deprecation of sdt-v1. And an addendum to the message for commit 00ee19ff030f66: removed some ancient symbol-table-only
probe-resolution code machinery. We can still probe that way, but the
code doesn't actively try to avoid pulling in debuginfo any more.
This test case is an unnecessary strain for the testsuite, because it
tries to enumerate tons of kernel probe points, but does nothing to
filter or assert correctness. It's a stress test only of the RAM of
the test machine.
PR25841 for dwarf probes: permit functions to use $context constructs
Major extension to expressivity to script functions. We now allow
them to use $context variables, as if they were written into each
probe point handler body where they are called (transitively) from.
This is accomplished by cloning such callgraphs-of-functions for
each probe, and expanding $context type operations from within
early during the probe derivation process.
This requires some gymnastics, because some symbol resolution needs to
happen -during- the derived-probe building time (when dwarf context
etc. are still available), not later when usual. To help this, the
systemtap_session object gets a current_resolver symresolution_info
field, which represents the "current" resolver that any of the various
derived-probe builders are using currently. This field is used in the
new function var_expanding_visitor::visit_functioncall(), to recurse
across function call boundaries.
In dwarf_cast_expanding_visitor::visit_cast_op and
dwarf_atvar_expanding_visitor::visit_atvar_op, the default "kernel"
module-name is removed as of --compatible=4.3, since the default is
inherited from the probe context itself.
This facility requires extensions from each probe point family type in
order to support. kernel.trace() cannot soon, and process.mark()
cannot just yet.
Almost all of the kmalloc() allocations exceeding 4KB have been
replaced by vmalloc(). This helps stap's kernel runtime work
properly on systems with serious fragmentation in physical memory
address space.
python support: prep our module enumerator script for python3
stap-resolve-module-function.py includes an "import imp", which
generates a stap-unfriendly deprecation warning. The code still
runs as of python 3.7, so simply squelching the warning for now.
PR12609 redux: filter out duplicate probes due to partial-inining
Ever since gcc 4.7ish, partially-inlined functions can sometimes show
up as separate top-level functions named FOO.part.* in the ELF symbol
table, but identifed as ordinary function FOO in DWARF. The latter
means that stap would probe both the partially inlined part of the
function, and the non-inlined second part, for a plain .function()
probe. This new code suppresses the probe on the .part. one, based
on a symbol name heuristic.
Recent changes related to synthetic-flagged probes interacted poorly
with an ancient commit 1ee0d3bab567, which thinks these probes are
in a sense negligible. Threading a new path between those heuristics
to ensure that
stap -l junk -E 'probe timer.s(1) { next }'
still fails, but synthetic-only probe scripts (like those triggered by
java.exp) are nevertheless accepted.
Craig Ringer [Sun, 29 Mar 2020 20:43:06 +0000 (16:43 -0400)]
PR25686: Fix ambiguous octal escapes in _stp_text_str
Tapset functions like user_buffer_quoted that use the _stp_text_str function
for octal escaping would produce incorrect output if a null byte was followed
by a byte that represents a printable digit in US-ASCII. The null byte would
be emitted in the shorthand \0 form, then the printable digit would be emitted
literally, resulting in (e.g.) \06 instead of \0006 for the two input bytes
"0x00 0x06".
Fix by disabling shorthand escapes for null bytes. The alternatives are to:
(a) look ahead in the buffer to see if the next byte is a digit and only
expand the \0 to \000 if it would be ambiguous; or
(b) octal-escape all printable digits
The second would be woeful for the intended function of human-readable-ish
buffer representations. The former seems potentially fragile and risky,
so I just went with simple.
Frank Ch. Eigler [Fri, 20 Mar 2020 23:03:56 +0000 (19:03 -0400)]
tapset docs: tweak SystemTap_Tapset_Reference overload.py for newer lxml
Newer versions do not have the write(doctype=...) parameters, as
noticed on some debian build attempts with --enable-docs
--enable-refdocs. Add stub info for a few parameters in
linux/ucontext-unwind.stp.
RHBZ1810216: fix ftrace() tapset function related autoconf test
It was reported that the ftrace() tapset function stopped working at
some point - due to an autoconf-* false negative. We failed to notice
because the tapset function was quietly mapped to a nop in this case.
Now ftrace() will #error in -p4 if autoconf doesn't detect a suitable
kernel facility. A forked testcase buildok/logging-embedded2.stp
checks for it.
I ran into the following compilation failure when I tried to change
$return in a return probe for some user-space process:
# ./runstap.sh
Pass 1: parsed user script and 478 library scripts using 238944virt/81096res/12424shr/68276data kb, in 790usr/230sys/1187real ms.
Pass 2: analyzed script: 3 probes, 6 functions, 1 embed, 2 globals using 255944virt/99036res/13544shr/85276data kb, in 300usr/70sys/449real ms.
Pass 3: translated to C into "/tmp/stapnWDsqi/stap_ea515d442eab2d1921c7105860f0337f_3673_src.c" using 255944virt/99364res/13872shr/85276data kb, in 270usr/430sys/716real ms.
In file included from /usr/share/systemtap/runtime/linux/runtime.h:217,
from /usr/share/systemtap/runtime/runtime.h:26,
from /tmp/stapnWDsqi/stap_ea515d442eab2d1921c7105860f0337f_3673_src.c:27:
/tmp/stapnWDsqi/stap_ea515d442eab2d1921c7105860f0337f_3673_src.c: In function ‘function___private___foobar_stp__dwarf_tvar_set_return_1’:
/usr/share/systemtap/runtime/linux/loc2c-runtime.h:297:69: error: ‘regnoo’ undeclared (first use in this function); did you mean ‘reg_info’?
#define u_store_register(regno,value) check_store_register(c->uregs,regnoo,_stp_is_compat_task()?ARRAY_SIZE(url_i386):ARRAY_SIZE(url_x86_64),value,uu_store_register)
^~~~~~
/usr/share/systemtap/runtime/linux/loc2c-runtime.h:44:23: note: in definition of macro ‘check_store_register’
if ((regs) == 0 || (regno) < 0 || (regno) > (maxregno)) { \
^~~~~
/tmp/stapnWDsqi/stap_ea515d442eab2d1921c7105860f0337f_3673_src.c:725:3: note: in expansion of macro ‘u_store_register’
u_store_register(0, l->__tmp0);
^~~~~~~~~~~~~~~~
/usr/share/systemtap/runtime/linux/loc2c-runtime.h:297:69: note: each undeclared identifier is reported only once for each function it appears in
#define u_store_register(regno,value) check_store_register(c->uregs,regnoo,_stp_is_compat_task()?ARRAY_SIZE(url_i386):ARRAY_SIZE(url_x86_64),value,uu_store_register)
^~~~~~
/usr/share/systemtap/runtime/linux/loc2c-runtime.h:44:23: note: in definition of macro ‘check_store_register’
if ((regs) == 0 || (regno) < 0 || (regno) > (maxregno)) { \
^~~~~
/tmp/stapnWDsqi/stap_ea515d442eab2d1921c7105860f0337f_3673_src.c:725:3: note: in expansion of macro ‘u_store_register’
u_store_register(0, l->__tmp0);
^~~~~~~~~~~~~~~~
make[1]: *** [scripts/Makefile.build:312: /tmp/stapnWDsqi/stap_ea515d442eab2d1921c7105860f0337f_3673_src.o] Error 1
make: *** [Makefile:1544: _module_/tmp/stapnWDsqi] Error 2
WARNING: kbuild exited with status: 2
Pass 4: compiled C into "stap_ea515d442eab2d1921c7105860f0337f_3673.ko" in 46720usr/15990sys/64098real ms.
Pass 4: compilation failed. [man error::pass4]
This failure is caused by a typo of the name of an argument variable
of macro u_store_register introduced at the commit a03b455bc656216a4829dbad08e630949d944c75.
Frank Sorenson [Fri, 7 Feb 2020 16:14:46 +0000 (10:14 -0600)]
Fix vfs.open probe use of 'cred' variable
Commit f6d683666 adjusted the vfs.open probe to obtain the $cred
target variable from a field of the $file target variable on
kernels where $cred is not available. This change missed a
second reference to the $cred target variable within the probe.
Fix the reference to the possibly-unavailable target variable
by referencing the systemtap variable just obtained.
Fixes: Commit f6d683666 ("Adjust the vfs_open to provide cred variable with 4.18 kernels") Signed-off-by: Frank Sorenson <sorenson@redhat.com>
Frank Ch. Eigler [Tue, 18 Feb 2020 21:45:04 +0000 (16:45 -0500)]
PR11249 etc.: tweak userspace function blacklist
Add some uretprobes blacklist entries for 32-on-64 function
__x86.get_pc_thunk.bx and its kin. Some bug between the kernel
uretprobes implementation and the systemtap runtime causes a SEGV on
the target process if a uretprobe is hit there. Add retblacklist.exp
to test.
Frank Ch. Eigler [Fri, 14 Feb 2020 21:10:22 +0000 (16:10 -0500)]
@var() diagnostics: generate more dwarf detail & context
For TLS-related variables like @var("errno") in glibc, some
useful diagnostic details were just dropped on the floor as
semantic_error objects were caught but not printed. New code
tries to arrange for these to be chained instead of lost. In
exchange, more errors would propagate to session.print_error
as chained to the target_symbol, so now the code also has to
duplicate-eliminate the chained errors.
The net result is that at verbosity 0 or 1, we appear to get only a
few specific and valuable incremental messages, which point to the
problematic dwarf. It would be nice to simplify this stuff, perhaps
by storing context (script-source level data, dwarf pointers, dwarf
contents, etc.) as RAII style global stack of "current details".
Serhei Makarov [Wed, 29 Jan 2020 18:23:05 +0000 (13:23 -0500)]
RHBZ1788662: update to work with older (>=3.3,<3.3) kernels
Older kernels (<3.13) lack rcu_is_watching() and instead have rcu_is_cpu_idle().
Yet older kernels (<3.3) lack rcu_is_cpu_idle(). Workaround there is disabled,
since the message on kernel commit #9b2e4f1880 suggests that older idle loops
would not trigger this problem, and those kernels should not have tracepoints
in idle loop.
Previous code in dump_symbol_tables() couldn't tolerate the case where
new elfutils opened /boot/vmlinuz* as an elf file for the kernel, and
could not extract a symbol table from that (nor an absent -debuginfo).
New code instead emits a warning and moves on. A special error code
triggers return to the dump_kallsyms() path that prior elfutils/stap
versions rely on.
Newer gcc does not recognize the fallthrough comment due to the text
following the fallthrough keyword. The "see above" doesn't seem too
valuable, so this patch drops it to fix the build.
Frank Ch. Eigler [Thu, 23 Jan 2020 18:35:30 +0000 (13:35 -0500)]
RHBZ1788662: check rcu_is_watching() before probe entry
Some tracepoints are problematic because they are called from an idle
context, where RCU/lockdep is not legal to call. On lockdep kernels,
RCU warnings and even possibly-related panics have been reported.
Kernel tracepoint handlers protect themselves by wrapping their
innards in rcu_irq_enter/rcu_irq_exit(), which flips the legality flag
back on (even during idle), but these functions are not
module-exported, and it's not clear they'd be sufficient anyway. So
we call the module-export'd rcu_is_watching() in
_stp_runtime_get_context() to reject any attempt to start a probe in
such an idling-cpu context. This covers the cpu_idle tracepoint as
well as others.
Frank Ch. Eigler [Thu, 23 Jan 2020 18:35:30 +0000 (13:35 -0500)]
RHBZ1788662: blacklist kernel cpu_idle tracepoint
This tracepoint is problematic because it is called from an idle
context, where RCU/lockdep is not legal to call. On lockdep kernels,
RCU warnings and even possibly-related panics have been reported.
Kernel tracepoint handlers protect themselves by wrapping their
innards in rcu_irq_enter/rcu_irq_exit(), which flips the legality flag
back on (even during idle), but these functions are not
module-exported, and it's not clear they'd be sufficient anyway. So
we blacklist in non-guru mode.
RHBZ1788648: parse arm64 sys/sdt.h operand format [x?, x?]
On arm64, the sys/sdt.h operand [x0, x1] was observed, and not
handled. New code in
sdt_uprobe_var_expanding_visitor::try_parse_arg_register_pair
recognizes that and parses it indirectly via
sdt_uprobe_var_expanding_visitor::try_parse_arg_effective_addr .
Sagar Patel [Tue, 12 Nov 2019 17:00:58 +0000 (12:00 -0500)]
PR22315: error handling support for stapbpf
This patch introduces enhancements for the BPF backend: try-catch block support,
error probes and an improved error tapset that works with the try-catch block
implementation.
The error tapset works as follows: if the error is called from a try block, the
program's execution will jump to the corresponding catch block. If the error is
called outside a try block, it gets registered and the program will terminate.
Epilogues are now added to each probe. The epilogue checks if an error occurred,
and calls a perf_event to print the error message. It also performs a check to
see if a MAXERRORS constraint is violated and if so, it signals a hard error to
the runtime via another perf_event.
It's worthwhile noting that error messages are copied into userspace (when the
error is registered) and then printed later (during epilogue). This is because
the BPF stack space is very limited which means the string cannot be efficiently
stored on the stack. If future versions of BPF permit more stack space, the
error message string could be stored directly onto the BPF stack instead of
storing it in userspace.
1) Added try-catch block generation and error probe handling.
2) Updated error tapset to work with try-catch statements.
3) Added new internal global variable, perf_events and BPF assembly statements.
4) Updated prologue to include a check for hard errors.
5) Designed epilogue which prints error messages and signals hard errors.
6) Added mapping for resource constraints set with -D.
7) Added test cases for the error tapset and try-catch blocks.
8) Updated NEWS.
The "Build-id mismatch" error now becomes a warning
It is normal for different binaries with the same file path coexist in
the same system via chroot or namespaces, therefore we make sure
build-id mismatch is really a warning instead of an error which leads
to non-zero exit codes of staprun.
For safety, we still make sure we do not register uprobes and etc to
wrong binaries when the build-id check fails.
Bug: MAXACTION errors + try/catch would lead to wrong src loc.
The MAXACTION error is not catchable but the try/catch code always
cleared its error message. Thus the source location reported was
inaccurate and always ended being the top-level try/catch statement's.
PR25290: process(EXE).begin probes might not get fired.
Occasionally the utrace callbacks might get called in the session state
of STAP_SESSION_STARTING so we have to be prepared to that otherwise
the user probe handler would never be called.
Also added a lot of debugging log output controlled by -DDEBUG_PROBES
and -DDEBUG_TASK_FINDER=LEVEL.
Sagar Patel [Thu, 19 Dec 2019 17:33:10 +0000 (12:33 -0500)]
PR25298: stapbpf unused blocks may cause segfault
The BPF optimizer removes unused blocks, however, it does not delete
all of the references to the deleted blocks. In the new implementation,
edges leading to the unused blocks are set as nullptr.
This increases the kernel module compilation parallelism level.
The Pass-4 is now about 700ms faster when --ldd is used for a
simple .stp script file using print_ubacktrace() on an Intel
Core i9-9900K machine.
For the dyninst runtime, the new CU is still compiled into the
resulting .so file but this backend is not using the symbols yet
and the compilation is not parallelized.
buildrun.cxx: make the stapconf_xxx.h file generation process parallellable.
This makes a typical .stp script's Pass-4 time reduces from 12.4s to
4.3s on a 8-core/16-thread system (Core i9-9900K) when stapconf_xxx.h
misses the cache.
Frank Ch. Eigler [Wed, 11 Dec 2019 20:50:10 +0000 (15:50 -0500)]
tapsets: multiple syscalls: __args type warnings
The __args symbol is used in several socket-related syscalls as a
place to put a type-enhanced pointer - or rather as two different
pointers (ulong vs uint pointers). This causes a stap warning.
Renaming this internal symbol avoids the warning. More syscalls
undoubtedly affected!
Frank Ch. Eigler [Wed, 27 Nov 2019 21:01:05 +0000 (16:01 -0500)]
stap-prep: speculative ubuntu/buildbot fixes
Attempt to eradicate recurrence of an intermittent buildbot error seen
internally, wherein debconf was complaining about "TERM unset ..." and
"PATH unset" etc.
Frank Ch. Eigler [Tue, 26 Nov 2019 23:25:20 +0000 (18:25 -0500)]
configury: drop bundled-elfutils mode
Bundling elfutils has only been necessary on systems that
lacked elfutils, and for some reason the normal autoconf
% LDFLAGS=-L/path/ CPPFLAGS=-I/path/ configure
trick didn't work. This kludge is now obstructing us as
some distro build (koji rawhide!) systems presume that even
conditional sources are real sources, and lead to failure.
So long, bundled-elfutils build mode, and thanks for all the fish.
Stan Cox [Fri, 15 Nov 2019 19:41:47 +0000 (14:41 -0500)]
Save entire register set for dyninst runtime on aarch64 and ppclle
Dyninst generated calls only allow register parms, so save register set in
chunks via successive calls to enter_dyninst_uprobe_regs:
arg1 = probe index arg2 = first regno in registers arg3... registers
* runtime/dyninst/uprobes-regs.c (enter_dyninst_uprobe_regs): New
* stapdyn/mutatee.cxx (get_dwarf_registers): Add aarch sp. Don't prune
ppcle and aarch64 register set.
(mutatee::instrument_dynprobe_target): Add dyninst snippet to generate
calls to enter_dyninst_uprobe_regs