Linux DTrace development list
 help / color / mirror / Atom feed
From: Kris Van Hees <kris.van.hees@oracle.com>
To: Jacob Carlborg <doob@me.com>
Cc: dtrace@lists.linux.dev
Subject: Re: [PATCH v2 3/3] libdtrace: match BEGIN/END PID in the tracer's own PID namespace
Date: Wed, 5 Aug 2026 13:12:43 -0400	[thread overview]
Message-ID: <anNvC9SSZEv6CiyQ@oracle.com> (raw)
In-Reply-To: <20260725180409.95012-4-doob@me.com>

Thank you for this patch.  I actually implemented the code to get the dev/ino
pair for the PID namespace in dt_vopen() so that we can store the values in
dtrace_hdl_t.  That way it is available to all places that need to retrieve
pidns-aware PID and TGID values.  I also added a function dt_cg_ns_pid_tgid()
to encapsulate the code to use the correct BPF helper based on whether we are
in the initial PID nameaspace or not, and I therefore modified your patch to
simply call that function rather than doing the work here.

I'm updating the other places in the code that need to be pidns-aware, and will
post the entire series once I am done with that.

I am also adding tests so that our testsuite going forward can ensure that
DTrace works in a PID namespace.

	Kris

On Sat, Jul 25, 2026 at 08:04:09PM +0200, Jacob Carlborg wrote:
> Without this fix, running any probe hangs with no output,
> like `dtrace -n 'BEGIN { trace("hi"); exit(0); }'`.
> 
> The issues is that the `BEGIN/END` probes are implemented as uprobes
> on DTrace's own `BEGIN_probe()/END_probe()` functions in `dt_work.c`.
> `bpf_get_current_pid_tgid()` reports the TGID in the initial PID
> namespace, which does not match `getpid()` when DTrace runs inside a
> PID namespace. Using the `--pid=host` flag when running OrbStack does
> not help, because it shares the daemon's namespace, not the kernel
> init namespace. OrbStack's own supervisor runs in a nested PID
> namespace. On bare metal `--pid=host` does reach the init namespaces
> and the bug wouldn't appear.
> 
> This fix is when DTrace is in a non-initial PID namespace and the
> kernel is at least 5.7, use `bpf_get_ns_current_pid_tgid` instead of
> `bpf_get_current_pid_tgid`. `bpf_get_ns_current_pid_tgid` is
> namespace aware.
> 
> Signed-off-by: Jacob Carlborg <doob@me.com>
> ---
>  libdtrace/dt_prov_dtrace.c | 58 ++++++++++++++++++++++++++++++++++----
>  1 file changed, 53 insertions(+), 5 deletions(-)
> 
> diff --git a/libdtrace/dt_prov_dtrace.c b/libdtrace/dt_prov_dtrace.c
> index 4b788507..179ee4d6 100644
> --- a/libdtrace/dt_prov_dtrace.c
> +++ b/libdtrace/dt_prov_dtrace.c
> @@ -9,6 +9,7 @@
>  #include <assert.h>
>  #include <errno.h>
>  #include <string.h>
> +#include <sys/stat.h>
> 
>  #include <bpf_asm.h>
> 
> @@ -129,12 +130,59 @@ static int trampoline(dt_pcb_t *pcb, uint_t exitlbl)
>          * the trampoline to minimize the cost of pointless firings in other
>          * tracers, even though this means preserving the context in %r1 around
>          * the call.
> +        *
> +        * bpf_get_current_pid_tgid() reports the TGID in the initial PID
> +        * namespace, which does not match getpid() when DTrace runs inside a
> +        * PID namespace (e.g. in a container) -- so the BEGIN/END probes would
> +        * never recognise their own firing and tracing would never activate.
> +        * When we are in a non-initial PID namespace on a kernel that provides
> +        * it (5.7+), use bpf_get_ns_current_pid_tgid() with DTrace's own PID
> +        * namespace so the value is reported in the same namespace as getpid().
> +        * Otherwise fall back to bpf_get_current_pid_tgid(), leaving the
> +        * initial-namespace case (and kernels < 5.7) exactly as before.
>          */
> -       emit(dlp, BPF_MOV_REG(BPF_REG_6, BPF_REG_1));
> -       emit(dlp, BPF_CALL_HELPER(BPF_FUNC_get_current_pid_tgid));
> -       emit(dlp, BPF_ALU64_IMM(BPF_RSH, BPF_REG_0, 32));
> -       emit(dlp, BPF_BRANCH_IMM(BPF_JNE, BPF_REG_0, getpid(), pcb->pcb_fastlbl));
> -       emit(dlp, BPF_MOV_REG(BPF_REG_1, BPF_REG_6));
> +       {
> +               struct stat     st;
> +               int             use_ns = 0;
> +               uint64_t        dev = 0, ino = 0;
> +
> +               /*
> +                * The initial PID namespace has a fixed inode number
> +                * (PROC_PID_INIT_INO, 0xEFFFFFFC).  If we are in it, getpid()
> +                * already agrees with bpf_get_current_pid_tgid() and no
> +                * namespace lookup is needed.
> +                */
> +               if (stat("/proc/self/ns/pid", &st) == 0 &&
> +                   st.st_ino != 0xEFFFFFFCULL &&
> +                   pcb->pcb_hdl->dt_kernver >= DT_VERSION_NUMBER(5, 7, 0)) {
> +                       use_ns = 1;
> +                       dev = st.st_dev;
> +                       ino = st.st_ino;
> +               }
> +
> +               emit(dlp, BPF_MOV_REG(BPF_REG_6, BPF_REG_1));
> +               if (use_ns) {
> +                       /*
> +                        * bpf_get_ns_current_pid_tgid(dev, ino, &nsinfo, sz)
> +                        * fills a struct bpf_pidns_info { u32 pid; u32 tgid; };
> +                        * the tgid is at offset 4.
> +                        */
> +                       dt_cg_xsetx(dlp, NULL, DT_LBL_NONE, BPF_REG_1, dev);
> +                       dt_cg_xsetx(dlp, NULL, DT_LBL_NONE, BPF_REG_2, ino);
> +                       emit(dlp, BPF_MOV_REG(BPF_REG_3, BPF_REG_FP));
> +                       emit(dlp, BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, DT_TRAMP_SP_SLOT(0)));
> +                       emit(dlp, BPF_MOV_IMM(BPF_REG_4, 8));
> +                       emit(dlp, BPF_CALL_HELPER(BPF_FUNC_get_ns_current_pid_tgid));
> +                       emit(dlp, BPF_LOAD(BPF_W, BPF_REG_0, BPF_REG_FP,
> +                                          DT_TRAMP_SP_SLOT(0) + 4));
> +               } else {
> +                       emit(dlp, BPF_CALL_HELPER(BPF_FUNC_get_current_pid_tgid));
> +                       emit(dlp, BPF_ALU64_IMM(BPF_RSH, BPF_REG_0, 32));
> +               }
> +               emit(dlp, BPF_BRANCH_IMM(BPF_JNE, BPF_REG_0, getpid(),
> +                                        pcb->pcb_fastlbl));
> +               emit(dlp, BPF_MOV_REG(BPF_REG_1, BPF_REG_6));
> +       }
> 
>         dt_cg_tramp_prologue_act(pcb, act);
> 
> --
> 2.50.1 (Apple Git-155)
> 
> 
> 

  reply	other threads:[~2026-08-05 17:12 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-20 13:30 [PATCH 0/3] Fix DTrace on modern kernels and in containers Jacob Carlborg
2026-07-20 13:30 ` [PATCH 1/3] libdtrace: resolve BTF type tags when importing BTF into CTF Jacob Carlborg
2026-07-24 20:09   ` Kris Van Hees
2026-07-20 13:30 ` [PATCH 2/3] libdtrace: derive io provider dev_name from the device model Jacob Carlborg
2026-07-20 13:31 ` [PATCH 3/3] libdtrace: match BEGIN/END PID in the tracer's own PID namespace Jacob Carlborg
2026-07-20 16:33 ` [PATCH 0/3] Fix DTrace on modern kernels and in containers Kris Van Hees
2026-07-21  6:27   ` Jacob Carlborg
2026-07-25 18:04 ` [PATCH v2 " Jacob Carlborg
2026-07-25 18:04   ` [PATCH v2 1/3] libdtrace: resolve BTF type tags transparently Jacob Carlborg
2026-07-25 18:04   ` [PATCH v2 2/3] libdtrace: derive io provider dev_name from the device model Jacob Carlborg
2026-07-25 18:04   ` [PATCH v2 3/3] libdtrace: match BEGIN/END PID in the tracer's own PID namespace Jacob Carlborg
2026-08-05 17:12     ` Kris Van Hees [this message]
2026-08-08 16:33       ` Jacob Carlborg

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=anNvC9SSZEv6CiyQ@oracle.com \
    --to=kris.van.hees@oracle.com \
    --cc=doob@me.com \
    --cc=dtrace@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox