[DTrace-devel] [oracle/dtrace-utils] 6420bf: config: add rule to check gcc option

Kris Van Hees noreply at github.com
Thu Feb 22 22:20:23 UTC 2024


  Branch: refs/heads/devel
  Home:   https://github.com/oracle/dtrace-utils
  Commit: 6420bf27926548e9430600162cf898c082cef75f
      https://github.com/oracle/dtrace-utils/commit/6420bf27926548e9430600162cf898c082cef75f
  Author: Kris Van Hees <kris.van.hees at oracle.com>
  Date:   2024-02-22 (Thu, 22 Feb 2024)

  Changed paths:
    M Makeconfig

  Log Message:
  -----------
  config: add rule to check gcc option

Signed-off-by: Kris Van Hees <kris.van.hees at oracle.com>
Reviewed-by: Nick Alcock <nick.alcock at oracle.com>


  Commit: 39e7324edfd05302dfaf99a0804aff7d154795b6
      https://github.com/oracle/dtrace-utils/commit/39e7324edfd05302dfaf99a0804aff7d154795b6
  Author: Kris Van Hees <kris.van.hees at oracle.com>
  Date:   2024-02-22 (Thu, 22 Feb 2024)

  Changed paths:
    M GNUmakefile
    M Makeconfig
    M configure

  Log Message:
  -----------
  bpf: add check for -mcpu=v3 BPFC option

Newer BPF gcc cross compilers emit instructions that older kernels do not
support yet.  Passing -mcpu=v3 disables using those instructions, but older
BPF cross compilers do not support that option.  Fortunately, those compilers
also do not emit the newer instructions.

Signed-off-by: Kris Van Hees <kris.van.hees at oracle.com>
Reviewed-by: Nick Alcock <nick.alcock at oracle.com>


  Commit: ee75f906fe038c6a9ce394e6bfc21e5203afd0d3
      https://github.com/oracle/dtrace-utils/commit/ee75f906fe038c6a9ce394e6bfc21e5203afd0d3
  Author: Nick Alcock <nick.alcock at oracle.com>
  Date:   2024-02-22 (Thu, 22 Feb 2024)

  Changed paths:
    M dtprobed/dtprobed.c
    M dtprobed/rpl_fuse_log.h
    M include/port.h
    M libport/daemonize.c

  Log Message:
  -----------
  dtprobed: logging improvements

So it turns out that fuse_log() isn't marked with any of GCC's printf
attributes. It's not so marked upstream, which is bad enough, but its
replacment isn't marked in our tree either, so all the fuse_log()s aren't
getting properly format-string checked.

Fix that, fix a bunch of them, and fix up the logging output so it usually
has timestamps in DTrace debug log format in it so testsuite output gets
properly split up and so that you can correlate debug output from dtprobed
with debug output from DTrace itself.

Tie it into the daemon logging machinery (which sends error messages up the
synchronization pipe after dtprobed has forked a daemonized child but before
it has finished initializing and its parent has died off, for printing by
the parent), so that fuse_log() can now be used everywhere without concern
for whether this code is being run before dtprobed has daemonized or not.
In the process, delete daemon_err(), a print-error-and-die function with
no remaining uses.

(Some format string errors remain after this commit, in code that is
outright removed or rewritten in the following commits.)

Signed-off-by: Nick Alcock <nick.alcock at oracle.com>
Reviewed-by: Kris Van Hees <kris.van.hees at oracle.com>


  Commit: de8ebd9e013029b3258584ee3f5178d491c81158
      https://github.com/oracle/dtrace-utils/commit/de8ebd9e013029b3258584ee3f5178d491c81158
  Author: Nick Alcock <nick.alcock at oracle.com>
  Date:   2024-02-22 (Thu, 22 Feb 2024)

  Changed paths:
    M Makeconfig
    A include/disasm.h
    M libdtrace/dt_pid.c

  Log Message:
  -----------
  dt_pid: fix building with upstream binutils

Upstream libopcodes (really, libbfd) requires the inclusion of BFD's
<config.h> before it will work.  Unfortunately, BFD's <config.h> is
not installed and is in any case absolutely chock-full of things we
do not want contaminating the DTrace build.  This is basically not
necessary on Linux (though it is on many more obscure platforms),
so most Linux distros patch the check out -- but it's still there
upstream, so we should handle it.

So introduce a new <disasm.h> header that wraps <dis-asm.h> and fools it
into believing that we have included BFD's <config.h> even though we
haven't.  To avoid breaking the configury tests, Makeconfig is adjusted to
look in our include/ directory for headers, and to test against our new
<disasm.h>.

Signed-off-by: Nick Alcock <nick.alcock at oracle.com>
Reviewed-by: Kris Van Hees <kris.van.hees at oracle.com>


  Commit: 84903ccb39e0ede30b167e3121bcdcbcd0b6d3cd
      https://github.com/oracle/dtrace-utils/commit/84903ccb39e0ede30b167e3121bcdcbcd0b6d3cd
  Author: Nick Alcock <nick.alcock at oracle.com>
  Date:   2024-02-22 (Thu, 22 Feb 2024)

  Changed paths:
    M dtprobed/Build
    A dtprobed/dof_stash.c
    A dtprobed/dof_stash.h
    M libcommon/dof_parser.h

  Log Message:
  -----------
  dtprobed: add the DOF stash

The DOF stash is a runtime directory (/run/dtrace by default) in which
the dtprobed daemon will keep track of incoming DOF.  There's a comment
describing it at the top of dtprobed/dof_stash.c, but in brief we have three
directories under this:

- stash/dof/, which contains raw DOF named by mapping
- stash/dof-pid/, which tracks DOF on a PID-by-PID and mapping-by-mapping
  basis. This contains subdirectories $pid/$mapping containing both the same
  raw DOF (hardlinked) and parsed DOF split up by probe, in
  $pid/$mapping/parsed/$prv:$mod:$fun$:prb.
- probes/, which contains parsed DOF for each individual probe in
  /run/dtrace/probes/$pid/$prv$pid/$mod/$fun/$prb to aid consumer globbing
  of probes; in future we may introduce further symlinks not in per-pid
  directories to ease matching of probes across processes.

Consumers can use inotify watches to detect newly added or removed DOF or
probes: because all the DOF is in one directory, a very small number of
watches is needed to keep track of all the DOF in the system, and only one
watch per PID is needed to track it on a PID-by-PID basis. (Currently,
nothing is doing this, but it is now a possibility where it never was
before.)

In a future commit, dtprobed will emit all the DOF it receives into this
structure, removing it when processes exit, and DTrace will use it to create
and remove probes.

dof_stash.c itself provides functions to add new raw DOF to the stash, to
add a stream of parsed DOF corresponding to a given piece of raw DOF to the
stash, to remove DOF as processes issue DTRACEHIOC_REMOVE requests, to check
for any DOF that needs reparsing to handle changes to struct dof_parsed, and
to remove entries from the DOF stash that is left behind by processes that
died uncleanly without issuing DTRACEHIOC_REMOVEs. (Currently, we don't deal
with newly-started processes that reuse the same PID as such a process, or
processes that leave DOF behind on exec() and then add more: this
improvement will come soon.)

It does not do any DOF parsing: that is left up to the caller (dtprobed.c).

All the writes to the dof_stash are done via the *at() functions to avoid
any risk of bugs causing the file creations and most especially deletions it
carries out from leaking outside /run/dtrace.  (We are not concerned about
symlink attacks etc because only root can write to /run/dtrace or any
directories underneath it.)

Signed-off-by: Nick Alcock <nick.alcock at oracle.com>
Reviewed-by: Kris Van Hees <kris.van.hees at oracle.com>


  Commit: bdef79a50a5b9b48a27f887841078a57b3ce29b9
      https://github.com/oracle/dtrace-utils/commit/bdef79a50a5b9b48a27f887841078a57b3ce29b9
  Author: Nick Alcock <nick.alcock at oracle.com>
  Date:   2024-02-22 (Thu, 22 Feb 2024)

  Changed paths:
    M libdtrace/dt_prov_dtrace.c

  Log Message:
  -----------
  dtrace provider: don't use functions from uprobes.h any more

This is about to go away, so the justification for using it (to make sure it
was frequently used and didn't rust) no longer applies.

This more or less reverts 5b43ff17f839195a29cadf255a947514d15aa478.

Signed-off-by: Nick Alcock <nick.alcock at oracle.com>
Reviewed-by: Kris Van Hees <kris.van.hees at oracle.com>


  Commit: 68ef5a7c82b092f16c39bee54e0b21e35298ec05
      https://github.com/oracle/dtrace-utils/commit/68ef5a7c82b092f16c39bee54e0b21e35298ec05
  Author: Nick Alcock <nick.alcock at oracle.com>
  Date:   2024-02-22 (Thu, 22 Feb 2024)

  Changed paths:
    M dtprobed/dtprobed.c

  Log Message:
  -----------
  dtprobed: handle signals hitting dtprobed better

dtprobed is long-running and thus might get hit by signals at almost any
time.  These will cause long-running operations to return -EINTR, which
needs handling.  We were handling -EINTR when a fuse_session_receive_buf()
happened, but dtprobed spends almost all its time blocked on poll() and that
isn't handling -EINTR at all.  This came to light when tests were written
that intentionally hit dtprobed with signals: fix it by checking the poll()
for EINTR too.  (Done in two places because the core FUSE loop is duplicated
for FUSE 2 and 3.)

Signed-off-by: Nick Alcock <nick.alcock at oracle.com>
Reviewed-by: Kris Van Hees <kris.van.hees at oracle.com>


  Commit: 4cee1da9dcd768868656a6d0e979e3da338285c5
      https://github.com/oracle/dtrace-utils/commit/4cee1da9dcd768868656a6d0e979e3da338285c5
  Author: Nick Alcock <nick.alcock at oracle.com>
  Date:   2024-02-22 (Thu, 22 Feb 2024)

  Changed paths:
    M dtprobed/dtprobed.c

  Log Message:
  -----------
  dtprobed: migrate away from parser_in_pipe/parser_out_pipe globals

These are very confusingly named: they are named from the parser child's
perspective.  In almost all dtprobed's codebase, parser_in_pipe is used for
*output*, and parser_out_pipe for *input*.  So introduce new globals that
are better named, and make the actual pipe-end arrays local.  (While we're
at it, switch process_dof() so it consistently uses its in/out parameters
rather than randomly using the globals now and then.)

Signed-off-by: Nick Alcock <nick.alcock at oracle.com>
Reviewed-by: Kris Van Hees <kris.van.hees at oracle.com>


  Commit: b09fcd41d97ff467aa0622b40ae834abda89b1b9
      https://github.com/oracle/dtrace-utils/commit/b09fcd41d97ff467aa0622b40ae834abda89b1b9
  Author: Nick Alcock <nick.alcock at oracle.com>
  Date:   2024-02-22 (Thu, 22 Feb 2024)

  Changed paths:
    M dtprobed/dtprobed.c

  Log Message:
  -----------
  dtprobed: make dof_read take a pid

It never uses the fuse_req_t it's passed for any other purpose.

Signed-off-by: Nick Alcock <nick.alcock at oracle.com>
Reviewed-by: Kris Van Hees <kris.van.hees at oracle.com>


  Commit: 2c27a586513ca07a24c4a79d29b6b21d3cc2ed1a
      https://github.com/oracle/dtrace-utils/commit/2c27a586513ca07a24c4a79d29b6b21d3cc2ed1a
  Author: Nick Alcock <nick.alcock at oracle.com>
  Date:   2024-02-22 (Thu, 22 Feb 2024)

  Changed paths:
    M dtprobed/dtprobed.c
    M dtprobed/dtprobed.service
    M dtrace.spec

  Log Message:
  -----------
  dtprobed: fill out the DOF stash

This commit arranges to create DOF stash entries corresponding to the probes
received by dtprobed when a DTRACEHIOC_ADDDOF is received from one of its
DOF-containing CUSE clients, and to remove them again when a
DTRACHIOC_REMOVE is received: at startup and at intervals (every 128
requests, an arbitrary value), the stash is scanned to remove entries
relating to processes that died before they had a chance to send a
DTRACEHIOC_REMOVE.

The stash is located under /run/dtrace by default, or under the directory
given by the new -s option to dtprobed.  This is mostly going to be used by
in-tree testing.  DTrace will gain a new dofstashpath option for the same
reason.  There is no need to document these: like dtprobed's -n option and
the DTRACE_DOF_INIT_DEVNAME environment variable, these are really only
testsuite internal implementation details.

Nothing is yet done with the stash: dtprobed still creates probes itself.

DOF-containing processes doing fork and exec have no effect on the stash as
yet: this will be fixed in a later commit.

Signed-off-by: Nick Alcock <nick.alcock at oracle.com>
Reviewed-by: Kris Van Hees <kris.van.hees at oracle.com>


  Commit: cb7c79725d627df26cd293c51356a8199dee2073
      https://github.com/oracle/dtrace-utils/commit/cb7c79725d627df26cd293c51356a8199dee2073
  Author: Nick Alcock <nick.alcock at oracle.com>
  Date:   2024-02-22 (Thu, 22 Feb 2024)

  Changed paths:
    M dtprobed/dtprobed.c

  Log Message:
  -----------
  dtprobed: reparse the DOF stash when needed

The DOF stash contains parsed DOF, i.e. instances of the dof_parsed_t
structure.  When this structure changes, we need to arrange to reparse all
DOF we have previously parsed that we find in the stash at daemon startup.

Doing this requires adjusting process_dof so its prototype is suitable to
pass to reparse_dof as a reparse function.  Since the reparse function may
be running long after the DOF itself is created, we can't go around grabbing
processes just to figure out their mapping (dev, ino)s: we can use the (dev,
ino) the DOF stash has already recorded.  This means migrating the process
grab out of process_dof() into a new mapping_dev_inum(), called by
process_dof()'s caller, helper_ioctl().

(This process temporarily breaks probe creation, since currently it
requires a ps_prochandle that is no longer available from process_dof.
It will be repaired in the next commit.)

Signed-off-by: Nick Alcock <nick.alcock at oracle.com>
Reviewed-by: Kris Van Hees <kris.van.hees at oracle.com>


  Commit: e71a20d8f2125c8e8a5f5f30720b0b68611c55e5
      https://github.com/oracle/dtrace-utils/commit/e71a20d8f2125c8e8a5f5f30720b0b68611c55e5
  Author: Nick Alcock <nick.alcock at oracle.com>
  Date:   2024-02-22 (Thu, 22 Feb 2024)

  Changed paths:
    M dtprobed/dtprobed.c
    M libcommon/Build
    R libcommon/uprobes.c
    R libcommon/uprobes.h
    M libdtrace/dt_impl.h
    M libdtrace/dt_open.c
    M libdtrace/dt_options.c
    M libdtrace/dt_pid.c
    M libdtrace/dt_pid.h
    M libdtrace/dt_proc.h
    M libdtrace/dt_prov_uprobe.c

  Log Message:
  -----------
  dt_pid, dtprobed: move uprobe creation to dtrace

Now the DOF stash is being created and populated, we can move all probe
creation to DTrace. This solves multiple problems:

 - removal of probes is difficult: dtprobed knows when all processes that
   registered DOF have unregistered it again, but that doesn't mean it's
   allowed to remove any of the corresponding uprobes. You can't remove a
   uprobe if it has any BPF associated with it, and the thing that does that
   is dtrace itself, which might well remove the BPF long after the
   processes that contained the corresponding uprobes are all dead: so
   dtrace is the only thing that can safely remove uprobes.

 - insertion of uprobes is limiting: passing the DTrace-side probe name down
   via probe arguments was clever, but alas probe arguments have much
   shorter maximum lengths than DTrace probes, so some valid DTrace probes
   cannot be registered as uprobes and end up with truncated names

 - it doesn't scale: the new probe registration/removal grinds to a halt
   after a few tens of thousands of uprobes are registered, and doing it
   here means that every probe that might potentially get used is created,
   even though any given DTrace invocation is only likely to use a subset
   of them.

The solution to this is to remove all the uprobe registration code from
dtprobed (goodbye, libcommon/uprobes.c) and migrate it all into
libdtrace/dt_prov_uprobe.c.  This is convenient because it's where PID probe
registration already happens, and it turns out we can reuse almost all the
code.

As for figuring out which probes to create, instead of pre-scanning the
/sys/kernel/debug/tracing/uprobe_events list and then looking for probes
that relate to the current process, we can just scan the /run/dtrace/probes
subdirectory in the DOF stash that relates to the specific PID we are
interested in (using globbing to identify the probes, taking advantage of
the fact that probespec globs follow the same rules as filesystem globs),
pull in the DOF, and generate probes from it.  Much simpler and much less
work.  (We do need to allow for processes dying as DTrace is processing
stash entries relating to them.)

The pre-parsing has one tiny caveat, which we can't even hit until we start
to reparse probes at runtime rather than just at DTrace startup. All the DOF
we need is already parsed by dtprobed, but if dtprobed was upgraded since
this instance of DTrace started, and the new dtprobed has a newer struct
dof_parsed, we want to ignore any such (too-new) parsed DOF and not register
the corresponding probes.  Earlier commits in this series introduced a new
DOF_PARSED_VERSION #define which is bumped whenever struct dof_parsed
changes and gets stuck at the start of all parsed DOF in the DOF stash: we
just need to compare that to what's baked into this copy of DTrace, and
avoid using any parsed DOF for which those are different.

Signed-off-by: Nick Alcock <nick.alcock at oracle.com>
Reviewed-by: Kris Van Hees <kris.van.hees at oracle.com>


  Commit: 12144eb287fb639322c87cd23aea988a2f01808a
      https://github.com/oracle/dtrace-utils/commit/12144eb287fb639322c87cd23aea988a2f01808a
  Author: Nick Alcock <nick.alcock at oracle.com>
  Date:   2024-02-22 (Thu, 22 Feb 2024)

  Changed paths:
    M dtprobed/dtprobed.c
    M runtest.sh

  Log Message:
  -----------
  dtprobed: a few test infrastructure improvements

The testsuite needs a few adjustments to cater for the DOF stash.  Firstly,
just as the testsuite instance of dtprobed uses a distinct device node, it
should also use a distinct DOF stash: putting it under the test tmpdir means
that it's even using the same filesystem type (tmpfs) as the DOF stash
usually does, without colliding with anything the systemwide instance may be
doing.

Also make the cleanup interval at which dtprobed cleans up dead internal
userdata structures and scans for kill -9'd processes in the DOF stash
configurable via the already-set _DTRACE_TESTING env var, and reduce it from
its default of 128 to 5, so that the cleanup code gets a good workout.

Also test the reparsing code (which by default would never kick in when the
testsuite ran at all, because the whole testsuite run is done with a single
daemon instance, so daemon upgrades are never relevant) by arranging to
kick off a forced reparse whenever the daemon is hit with a SIGUSR2.  (A
test added in a future commit will use this.)

Finally, avoid prefixing log messages with "dtprobed DEBUG $timestamp: "
when not testing: it's formatted like that to force inclusion in the
runtest.log as a trace message, but it's emitted even for non-debugging
messages so is more than a bit confusing.  Make it a testsuite-only
thing.

Signed-off-by: Nick Alcock <nick.alcock at oracle.com>
Reviewed-by: Kris Van Hees <kris.van.hees at oracle.com>


  Commit: 12ed428733a141c40eede9468b3c3bc169574096
      https://github.com/oracle/dtrace-utils/commit/12ed428733a141c40eede9468b3c3bc169574096
  Author: Nick Alcock <nick.alcock at oracle.com>
  Date:   2024-02-22 (Thu, 22 Feb 2024)

  Changed paths:
    M libcommon/dof_parser.h
    M libcommon/dof_parser_host.c

  Log Message:
  -----------
  dof_parser: a bit of const-correctness

dof_parser_host_write does not change its dh argument, so make it const.

Signed-off-by: Nick Alcock <nick.alcock at oracle.com>
Reviewed-by: Kris Van Hees <kris.van.hees at oracle.com>


  Commit: 5dd00017625a1d89a2824e9ebf8f9000e33877ca
      https://github.com/oracle/dtrace-utils/commit/5dd00017625a1d89a2824e9ebf8f9000e33877ca
  Author: Nick Alcock <nick.alcock at oracle.com>
  Date:   2024-02-22 (Thu, 22 Feb 2024)

  Changed paths:
    M libdtrace/dt_proc.c
    M libproc/Pcontrol.c
    M libproc/libproc.h

  Log Message:
  -----------
  proc: don't ptrace shortlived-grabbed processes if someone else is ptracing them

Shortlived grabs, by definition, are grabs that won't last long and where we
don't expect things like dlopen monitoring to be useful.  We ptrace for
this, and to extract dynamic loader scope info and take things like symbol
interposition into accout when doing symbol lookup; but if someone else is
already tracing the process we should probably just try not ptracing it,
since the worst that will happen if we do is that some name lookups of
interposed symbols or symbols in alternate dlmopen namespaces might yield
the wrong address (probably leading to a probe not firing when it
should).

Interposed symbols are rare enough that this failure mode is probably not
justification for refusing to trace entirely (perhaps a warning message
might be desirable, but honestly I think it's rare enough that not even that
is justifiable: most ptrace failures will have no visible negative
consequences at all, since not only must an interposed symbol exist but we
must also be tracing it *and* tracing the process with multiple debuggers at
once, which seems likely to be very rare: nearly all warnings will be
warning when nothing will go wrong at all).

It is even rarer in the modern toolchain world in which many ELF objects
cannot be interposed at all, whether due to -z now or
-fno-semantic-interposition or whatever.

Doing this makes it practical to have multiple dtraces USDT-probing the same
process at the same time: one of them will ptrace it, the other one won't,
and both will get the mapping info they need for a
reliable-enough-to-be-useful trace (and if we're lucky and can ptrace,
symbol resolution quality goes up a bit).

test/unittest/usdt/tst.multitrace.sh tests this (though there are other
things stopping it working well, it cannot work at all without something
like this).

Signed-off-by: Nick Alcock <nick.alcock at oracle.com>
Reviewed-by: Kris Van Hees <kris.van.hees at oracle.com>


  Commit: 4f528b14bf3bac39b4adbbcb40ff594f0288dd17
      https://github.com/oracle/dtrace-utils/commit/4f528b14bf3bac39b4adbbcb40ff594f0288dd17
  Author: Nick Alcock <nick.alcock at oracle.com>
  Date:   2024-02-22 (Thu, 22 Feb 2024)

  Changed paths:
    M runtest.sh
    M test/unittest/usdt/tst.dlclose2.sh
    M test/unittest/usdt/tst.manyprocs.sh
    M test/unittest/usdt/tst.multitrace.sh

  Log Message:
  -----------
  usdt: test improvements

This soups up test/unittest/usdt/tst.manyprocs.sh to test dtprobed's
cleaning up the wreckage of dead processes, by having every other process
kill itself rather than dying peacefully (and sending a DTRACEHIOC_REMOVE).
When doing in-tree testing (something we can detect via $dtrace), we can
also check the DOF stash itself to see whether the wreckage has been cleaned
up. (This isn't practical when doing systemwide testing because we don't
know how much DOF the dtprobed might legitimately be hanging on to.)

tst.multitrace.sh gains the ability to test DOF reparsing on upgrade,
waiting until the first probe-containing process has started and then
intentionally overwriting some of the parsed DOF with junk (in lieu of
actually changing struct dof_parsed on the fly :) ) and forcing a reparse
via a kill -USR2 (in lieu of communicating the complete argument list of
dtprobed down to this test just so it can be killed and restarted).

Signed-off-by: Nick Alcock <nick.alcock at oracle.com>
Reviewed-by: Kris Van Hees <kris.van.hees at oracle.com>


  Commit: 68bb9a0acea5a60ceb32025e822c4f597846c102
      https://github.com/oracle/dtrace-utils/commit/68bb9a0acea5a60ceb32025e822c4f597846c102
  Author: Nick Alcock <nick.alcock at oracle.com>
  Date:   2024-02-22 (Thu, 22 Feb 2024)

  Changed paths:
    M test/unittest/usdt/tst.manyprobes.sh

  Log Message:
  -----------
  Revert "test: Have manyprobes clean up uprobes"

This reverts commit 8dedee6fc6ef58c3818a32d84d2acc4bf87b1dce, and
also drops the pre-existing ugly echo kludge.

We have proper cleanup now.

Signed-off-by: Nick Alcock <nick.alcock at oracle.com>
Reviewed-by: Kris Van Hees <kris.van.hees at oracle.com>


  Commit: 1cb80377eb3729e1e40daca971131fbbc4c149d4
      https://github.com/oracle/dtrace-utils/commit/1cb80377eb3729e1e40daca971131fbbc4c149d4
  Author: Nick Alcock <nick.alcock at oracle.com>
  Date:   2024-02-22 (Thu, 22 Feb 2024)

  Changed paths:
    M dtprobed/dof_stash.c
    M dtprobed/dof_stash.h
    M dtprobed/dtprobed.c
    A test/unittest/usdt/tst.exec-dof-replacement.r
    A test/unittest/usdt/tst.exec-dof-replacement.r.p
    A test/unittest/usdt/tst.exec-dof-replacement.sh

  Log Message:
  -----------
  dtprobed: empty the DOF stash for exec()ed processes

The DOF stash, and USDT in general, currently have problems with fork()ed
and exec()ed processes. The worst of these problems is with exec().  Since
exec() replaces a process image with another atomically, ELF destructors do
not get to run, so dtprobed never receives a DTRACEHIOC_REMOVE request for
any of the DOF in it.  If the exec()ed process also contains DOF, this DOF
will add to the DOF already in the stash, and DTrace will think that the
exec()ed process contains all the probes in the original process in addition
to its own.

The fix is fairly simple, though it involves a bit of annoying refactoring:
record the (dev, ino) of the executable mapping of every process
contributing DOF in a new dof-pid file "exec-mapping", then compare this
with the executable mapping of the contributing procerss when new DOF is
contributed.  Any exec() will necessarily change this and we can clean out
the old DOF dir (hence the refactoring, since this adds a second thing
beyond stale process cleanup that wants to delete whole PIDs out of the DOF
stash).

Testing this is a little painful because DTrace proper does not detect
exec() and rescan for new USDT probes (it would also need to wait until the
new process had run its drti ELF constructor); but it can be done.

Technically there is still one case in which the DOF can go stale: if a
process does dlopen()s, then exec()s itself.   This is fixable (by detecting
new-DOF contributions from a mapping that we already know about for this
PID), but is a slightly distinct fix with a different testcase, so is best
put in a separate commit.

Signed-off-by: Nick Alcock <nick.alcock at oracle.com>
Reviewed-by: Kris Van Hees <kris.van.hees at oracle.com>


  Commit: 6b59a97faf18b797c6df4d9c5d1de1a3ac6e809a
      https://github.com/oracle/dtrace-utils/commit/6b59a97faf18b797c6df4d9c5d1de1a3ac6e809a
  Author: Nick Alcock <nick.alcock at oracle.com>
  Date:   2024-02-22 (Thu, 22 Feb 2024)

  Changed paths:
    M Makeconfig
    M include/sys/compiler.h
    M libdtrace/drti.c

  Log Message:
  -----------
  drti: re-register DOF after fork

DTrace v2 doesn't automatically copy tracing sessions across fork boundaries
the way v1 used to (in the kernel).  Instead. re-register DOF in the forked
child just like it was registered for the original process at ELF
constructor invocation time.

We do this using pthread_atfork, but older glibc puts pthread_atfork in
-lpthread which clients are obviously not required to link with; so we spot
such old glibcs and directly call the corresponding not-exactly-internal
glibc function if found.  This function is always in libc; a call to it is
found in libc_nonshared and it is directly used by systemd, so it's
ABI-stable and safe to call.)

In the process, clean up some messes: moving the device file I/O into a
separate function means we no longer need to close it on error in a dozen
places; don't mess around with temporary variables just to open
/proc/self/maps, which is a literal string (back in the day it used to be
/proc/%i/maps where %i was getpid(), but not for years).

(Technically, calling ioctl() from a pthread_atfork() handler is dodgy as it
is not async-signal-safe. In practice, in this implementation, it's fine.
The use of dprintf() in error messages is more likely to be problematic.)

Signed-off-by: Nick Alcock <nick.alcock at oracle.com>
Reviewed-by: Kris Van Hees <kris.van.hees at oracle.com>


  Commit: f43dd80951993b79217248285a0072f0a5bf3682
      https://github.com/oracle/dtrace-utils/commit/f43dd80951993b79217248285a0072f0a5bf3682
  Author: Nick Alcock <nick.alcock at oracle.com>
  Date:   2024-02-22 (Thu, 22 Feb 2024)

  Changed paths:
    M libdtrace/drti.c

  Log Message:
  -----------
  drti: async-signal-safeize

The last commit left dtrace_dof_register() calling dprintf(), which is not
async-signal-safe and is quite likely to call malloc() (and in the glibc
implementation, it does).  A fork at the wrong time in a multithreaded
process (while a malloc lock is taken out in some other thread) could
deadlock here in the child, which is distinctly unfortunate for what is
basically debugging output.  (Other uses of malloc are probably fine in the
forked child itself, though hilariously POSIX doesn't even guarantee that;
but in some glibc releases the malloc lock release that implements that is
done by an atfork handler, which may be called after this one: so this
atfork handler cannot rely on the malloc arena being in a useful state for
allocation.)

Because all the dprintf()s in dtrace_dof_register depend only on the dofhp,
which never varies for a given ELF object for the lifetime of the process
(and any forked children), we can asprintf() them at constructor time, and
write() them out in dtrace_dof_register(), and free them in the
destructor. write() is async-signal-safe.  Most are debugging output, so if
allocation fails we just don't print anything: but ioctl failure is always
printed, so substitute an unvarying message if allocation fails.

Signed-off-by: Nick Alcock <nick.alcock at oracle.com>
Reviewed-by: Kris Van Hees <kris.van.hees at oracle.com>


  Commit: d9fbbe827c22bbac75a2a0583425716a2215de03
      https://github.com/oracle/dtrace-utils/commit/d9fbbe827c22bbac75a2a0583425716a2215de03
  Author: Nick Alcock <nick.alcock at oracle.com>
  Date:   2024-02-22 (Thu, 22 Feb 2024)

  Changed paths:
    M libproc/elfish.c

  Log Message:
  -----------
  libproc: fix buffer overread if no auxvs are read

It is possible (though unlikely) for /proc/$pid/auxv to be empty when we
read it (perhaps the process died at just the wrong instant).  We should
bound our searches by the number of auxvs (which we know), and not just rely
on the last one being AT_NULL (though we should check that too because some
arches truncate auxv lists by introducing AT_NULLs).

Signed-off-by: Nick Alcock <nick.alcock at oracle.com>
Reviewed-by: Kris Van Hees <kris.van.hees at oracle.com>


  Commit: b5b9bd82346a669448cda91e1a0324d6a75a43b8
      https://github.com/oracle/dtrace-utils/commit/b5b9bd82346a669448cda91e1a0324d6a75a43b8
  Author: Nick Alcock <nick.alcock at oracle.com>
  Date:   2024-02-22 (Thu, 22 Feb 2024)

  Changed paths:
    M libdtrace/dt_proc.c

  Log Message:
  -----------
  proc: do not access freed memory when discarding shortlived handles

Signed-off-by: Nick Alcock <nick.alcock at oracle.com>
Reviewed-by: Kris Van Hees <kris.van.hees at oracle.com>


  Commit: 5c20436dbd6030ecaa5365237dfaad771eeff990
      https://github.com/oracle/dtrace-utils/commit/5c20436dbd6030ecaa5365237dfaad771eeff990
  Author: Nick Alcock <nick.alcock at oracle.com>
  Date:   2024-02-22 (Thu, 22 Feb 2024)

  Changed paths:
    M libdtrace/dt_link.c

  Log Message:
  -----------
  Revert "usdt: remove relocations rather than changing their type to R_*_NONE"

This reverts commit 2096fd774aa7459bb106337dc600acc25b31f3d6.

(Adjusted to keep the test in that commit.)


  Commit: 4b3c85530af9c28dfd803ae680d6928a84084840
      https://github.com/oracle/dtrace-utils/commit/4b3c85530af9c28dfd803ae680d6928a84084840
  Author: Nick Alcock <nick.alcock at oracle.com>
  Date:   2024-02-22 (Thu, 22 Feb 2024)

  Changed paths:
    M test/unittest/usdt/tst.static2.sh

  Log Message:
  -----------
  Revert "test: Add xfail pending binutils fix"

This reverts commit 06eb21821691c333b8917ccd6982d6940333f0b9.


  Commit: e5de442fd83a16fa121cc5013fbc5e2c0e3a6c10
      https://github.com/oracle/dtrace-utils/commit/e5de442fd83a16fa121cc5013fbc5e2c0e3a6c10
  Author: Nick Alcock <nick.alcock at oracle.com>
  Date:   2024-02-22 (Thu, 22 Feb 2024)

  Changed paths:
    M dtprobed/dtprobed.c

  Log Message:
  -----------
  dtprobed: fix label indentation

Trivial style fix.

Signed-off-by: Nick Alcock <nick.alcock at oracle.com>
Reviewed-by: Kris Van Hees <kris.van.hees at oracle.com>


  Commit: 68a085db051067b1875a102f4d1ff887047742e9
      https://github.com/oracle/dtrace-utils/commit/68a085db051067b1875a102f4d1ff887047742e9
  Author: Eugene Loh <eugene.loh at oracle.com>
  Date:   2024-02-22 (Thu, 22 Feb 2024)

  Changed paths:
    M libdtrace/dt_impl.h

  Log Message:
  -----------
  Fix sizw typo

Signed-off-by: Eugene Loh <eugene.loh at oracle.com>
Reviewed-by: Kris Van Hees <kris.van.hees at oracle.com>


  Commit: f3e41146f49789f6571773ba95b67fbf34fd392a
      https://github.com/oracle/dtrace-utils/commit/f3e41146f49789f6571773ba95b67fbf34fd392a
  Author: Eugene Loh <eugene.loh at oracle.com>
  Date:   2024-02-22 (Thu, 22 Feb 2024)

  Changed paths:
    M libdtrace/dt_aggregate.c

  Log Message:
  -----------
  Remove dead code

Signed-off-by: Eugene Loh <eugene.loh at oracle.com>
Reviewed-by: Kris Van Hees <kris.van.hees at oracle.com>


  Commit: 6e99a62983964b5cce139f1dfa28485fde9f0405
      https://github.com/oracle/dtrace-utils/commit/6e99a62983964b5cce139f1dfa28485fde9f0405
  Author: Eugene Loh <eugene.loh at oracle.com>
  Date:   2024-02-22 (Thu, 22 Feb 2024)

  Changed paths:
    M test/demo/fbt/delay.d
    M test/unittest/printa/tst.stack.d

  Log Message:
  -----------
  test: Reduce a few tests' vulnerability to large agg sizes

Signed-off-by: Eugene Loh <eugene.loh at oracle.com>
Reviewed-by: Kris Van Hees <kris.van.hees at oracle.com>


  Commit: e3c8b283b7d862a052b797281bf1f9c295529b23
      https://github.com/oracle/dtrace-utils/commit/e3c8b283b7d862a052b797281bf1f9c295529b23
  Author: Eugene Loh <eugene.loh at oracle.com>
  Date:   2024-02-22 (Thu, 22 Feb 2024)

  Changed paths:
    A test/unittest/options/tst.flowindent.aarch64.r
    M test/unittest/options/tst.flowindent.d
    R test/unittest/options/tst.flowindent.r
    A test/unittest/options/tst.flowindent.r.p
    A test/unittest/options/tst.flowindent.x86_64.r

  Log Message:
  -----------
  test: Clean up flowindent test

The flowindent test was marked XFAIL, claiming that
"flowindent is broken," but arguably the situation is more
nuanced than that.

The flowindent formatting is perhaps always going to be not completely
robust.  Each call to dt_consume_cpu() resets flowindent state.  This
is "necessarily" so, since data from different CPUs can be very difficult
(for multiple reasons) to interweave in any sensible fashion.

Therefore, adapt the test to jump less between CPUs.  For example,
trace only the target process:  /pid == $target/.

Further, improve the chances of a CPU finishing writing to its
buffer before the consumer tries to read the buffer.  E.g., employ
a switchrate:  -xswitchrate=1s.  Since this consumer throttling
takes a moment to kick in, do not worry about the first few probe
firings -- see tst.flowindent.r.p.

While we're at it, remove the unneeded tick probes.

Finally, not only update the .r results file, but also add such a
file for aarch64.

Signed-off-by: Eugene Loh <eugene.loh at oracle.com>
Reviewed-by: Kris Van Hees <kris.van.hees at oracle.com>


  Commit: 7f04600dce4aa9a70c6200e5dd316c8f84bbfa31
      https://github.com/oracle/dtrace-utils/commit/7f04600dce4aa9a70c6200e5dd316c8f84bbfa31
  Author: Eugene Loh <eugene.loh at oracle.com>
  Date:   2024-02-22 (Thu, 22 Feb 2024)

  Changed paths:
    M test/unittest/io/check_io_probe_args.sh
    M test/unittest/io/tst.local2.sh
    M test/unittest/io/tst.nfs2.sh

  Log Message:
  -----------
  test: Add more diagnostic info to io tests

Signed-off-by: Eugene Loh <eugene.loh at oracle.com>
Reviewed-by: Kris Van Hees <kris.van.hees at oracle.com>


  Commit: 5265bb3876604f4bae5ad6c7fb946f39dd59ea97
      https://github.com/oracle/dtrace-utils/commit/5265bb3876604f4bae5ad6c7fb946f39dd59ea97
  Author: Eugene Loh <eugene.loh at oracle.com>
  Date:   2024-02-22 (Thu, 22 Feb 2024)

  Changed paths:
    M test/modules

  Log Message:
  -----------
  test: Add nfs to list of modules for testing

Certain functionality and tests depend on the nfs module being loaded,
such as during an nfs mount operation.

Some tests, however, such as test/unittest/disasm/tst.ann-tramp-lvar.sh,
check for behavior that depends on nfs probes without the test itself
performing any nfs operations.

Add nfs to the test modules list.

Signed-off-by: Eugene Loh <eugene.loh at oracle.com>
Reviewed-by: Kris Van Hees <kris.van.hees at oracle.com>


  Commit: 0bc774a4eccfdef659cb3d719903e69324811cf5
      https://github.com/oracle/dtrace-utils/commit/0bc774a4eccfdef659cb3d719903e69324811cf5
  Author: Eugene Loh <eugene.loh at oracle.com>
  Date:   2024-02-22 (Thu, 22 Feb 2024)

  Changed paths:
    M test/unittest/io/tst.local2.sh
    M test/unittest/io/tst.nfs2.sh

  Log Message:
  -----------
  test: Make io tests a little more lenient

Signed-off-by: Eugene Loh <eugene.loh at oracle.com>
Reviewed-by: Kris Van Hees <kris.van.hees at oracle.com>


  Commit: 7857c51a7317ffb11211ed1a569f3f29940e9bf4
      https://github.com/oracle/dtrace-utils/commit/7857c51a7317ffb11211ed1a569f3f29940e9bf4
  Author: Eugene Loh <eugene.loh at oracle.com>
  Date:   2024-02-22 (Thu, 22 Feb 2024)

  Changed paths:
    M test/unittest/io/check_io_probe_args.sh

  Log Message:
  -----------
  test: Modify script to handle here strings with OL7

Signed-off-by: Eugene Loh <eugene.loh at oracle.com>
Reviewed-by: Kris Van Hees <kris.van.hees at oracle.com>


  Commit: 7caa1df6325eacf9ddf041a29a6c8600789dacb4
      https://github.com/oracle/dtrace-utils/commit/7caa1df6325eacf9ddf041a29a6c8600789dacb4
  Author: Kris Van Hees <kris.van.hees at oracle.com>
  Date:   2024-02-22 (Thu, 22 Feb 2024)

  Changed paths:
    M test/unittest/usdt/tst.link-idempotence.sh

  Log Message:
  -----------
  test: Reduce volume of test log output for link-idempotence

Spare 100s to 1000s of lines of output in the normal, PASS case.

Inspired-by: Eugene Loh <eugene.loh at oracle.com>
Signed-off-by: Kris Van Hees <kris.van.hees at oracle.com>
Reviewed-by: Eugene Loh <eugene.loh at oracle.com>


Compare: https://github.com/oracle/dtrace-utils/compare/7f2b6c93a4b4...7caa1df6325e

To unsubscribe from these emails, change your notification settings at https://github.com/oracle/dtrace-utils/settings/notifications



More information about the DTrace-devel mailing list