[DTrace-devel] top-of-file comment for one-parse-per-mapping world (was Re: [PATCH v3 06/21] dtprobed: add the DOF stash)

Nick Alcock nick.alcock at oracle.com
Wed Feb 14 17:21:24 UTC 2024


On 12 Feb 2024, Nick Alcock stated:

> On 12 Feb 2024, Kris Van Hees spake thusly:
>
>> Initial comments (mostly on the comments, that are pretty crucial for people
>> to understand what is going on here).
>
> ... here's the new top-of-file comment block, which hopefully make a bit
> more sense now:
[...]

... and here's what it might look like in a one-file-per-mapping world:

 * The state storage structure is as follows:
 *
 * /run/dtrace/stash/: Things private to dtprobed.
 *
 *    .../dof/$dev-$ino/: DOF contributed by particular mappings (as
 *    received from some probe-containing program).
 *
 *    .../dof/$dev-$ino/raw: raw DOF, precisely as received
 *
 *    .../dof/$dev-$ino/parsed: parsed DOF, dofhp_addr-independent (as
 *    if dofhp_addr were 0).
 *
 *    .../dof/$dev-$ino/relocs: unknown reloc-like indications of what
 *    offsets in "parsed" to adjust to apply a dofhp_addr with a given
 *    offset (... maybe just a straight list of 64-bit file offsets?)
 *
 *    .../dof-pid/$pid/$dev-$ino/: contains everything relating to DOF
 *    contributed by a particular USDT-containing ELF object within a given
 *    process (henceforth "DOF source").  Each DTRACEHIOC_ADDDOF ioctl call
 *    creates one of these.
 *
 *    .../dof-pid/$pid/$gen: symlink to a single $dev-$ino dir. "$gen" is an
 *    incrementing generation counter starting at zero for every unique PID,
 *    used to uniquely identify DOF pieces to remove.
 *
 *    .../dof-pid/$pid/next-gen: The next generation counter to use for a new
 *    piece of DOF from this process.  Encoded as a sparse file whose size is
 *    the next counter value to use.
 *
 *    .../dof-pid/$pid/exec-mapping: a dev/ino pair in the form
 *    $dev-$ino (as in the $dev-$ino directory entries): the dev/ino of the
 *    process's primary text mapping, as given by libproc.
 *
 *    .../dof-pid/$pid/$dev-$ino/raw: hardlink to the raw DOF for
 *    a given DOF source.  Pruned of dead processes at startup and on
 *    occasion: entries also deleted on receipt of DTRACEHIOC_REMOVE
 *    ioctls.  A hardlink is used in order to bump the link count for
 *    the corresponding parsed DOF in the dof/$dev-$ino/ directory: when this
 *    link count falls to 1, the DOF is considered dead and the
 *    corresponding probe is removed.
 *
 *    .../dof-pid/$pid/$dev-$ino/dh: Raw form of the dof_helper_t received from
 *    a given DTRACEHIOC_ADDDOF, serialized straight to disk with no changes.
 *    Preserved for all DTRACEHIOC_ADDDOFs, even if the DOF was already
 *    contributed by some other process.  Keeping this around allows the DOF to
 *    be re-parsed as needed, even by a later re-execution of a different
 *    version of the same daemon with a different dof_parsed_t structure, and to
 *    be re-parsed with appropriate addresses for whichever mapping of this DOF
 *    is under consideration.
 *
 *    .../dof-pid/$pid/$dev-$ino/parsed/: Directory containing broken-up
 *    parsed DOF for a given DOF source.  Deleted when empty.
 *
 *    .../dof-pid/$pid/$dev-$ino/parsed/all: parsed DOF (from
 *    /dof/$dev-$ino/parsed) with relocs applied given dof-pid/.../dh
 *    and dof-pid/.../relocs.  Deleted at daemon startup if the
 *    dof_parswed_t structure changes.  The file consists of a
 *    uint64_t version number (DOF_PARSED_VERSION), a uint64_t count of
 *    tracepoints, and then that many struct dof_parsed_t's of type
 *    DIT_TRACEPOINT.  Broken up into...
 *    # (... may not need this one at all, we might be able to reloc and
 *    #  cut into chunks simultaneously? there is no other use for this
 *    #  file other than generating the split-up parsed stuff below.)
 *
 *    .../dof-pid/$pid/$dev-$ino/parsed/$prv$pid:$mod:$fun:$prb: ...
 *    parsed DOF for a given PID/mapping/probe triplet, from
 *    dof/$dev-$ino/parsed with relocs from dof/$dev-$ino/relocs
 *    applied, given the addresses in .../dh.  Deleted at daemon startup
 *    if the dof_parsed_t structure changed.
 *
 * /run/dtrace/probes/: Per-probe info, written by dtprobed, read by DTrace.
 *
 *    .../$pid/$prv$pid/$mod/$fun/$prb: Hardlink from $prv$pid:$mod:$fun:$prb
 *    above; parsed representation of one probe in a given process. Removed by
 *    dtprobed when the process dies, or if all mappings containing the probe
 *    are unmmapped.  Used by DTrace for tracing by PID.
 *
 *    (If a probe exists in multiple different mappings in a given process, they
 *    must all be identical.)
 *
 * In future, symlinks in /run/dtrace/probes/$prv$pid may exist, used for
 * globbing provider names across processes.

The dof_parsed_t gains a new enumerand DIT_RELOC connected to this new
entry in the unnamed union in dof_parsed_t (DOF_PARSED_VERSION 2):

		struct dpi_reloc {
			/*
			 * A location needing dofhp_addr-relative relocation.
			 */
			size_t offset;
		};

The parser stuffs these into the parser stream whenever it currently
applies a reloc (in dof_slurp()).  dof_stash.c can then trivially run
down these, write them to /relocs, and later use those to apply relocs
to the DOF to emit per-PID, per-mapping DOF without reparsing anything
or relying on the dofhp_addr at parse time.  We don't need a reloc type
or anything because the parser only applies one type of reloc anyway :)

... does this make sense?



More information about the DTrace-devel mailing list