diff options
author | Luca Bruno <lucab@lucabruno.net> | 2023-08-31 13:46:16 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-08-31 07:46:16 -0400 |
commit | 442f658dc22d70bb024cac448932e27090d4a965 (patch) | |
tree | a851184c61198559c275871a6be296f5120b4fe1 | |
parent | 9596edb9415197aa52d771b65581a73b89f3f4dc (diff) | |
download | bcc-442f658dc22d70bb024cac448932e27090d4a965.tar.gz |
tools/profile: add support for PID-namespacing (#4709)
This adds translation logic to perform PID translation across
PID-namespaces.
It is now possible to profile a target process from within a
nested PID-namespace (e.g. in a container).
Also add a note in profile_example.txt file.
-rwxr-xr-x | tools/profile.py | 26 | ||||
-rw-r--r-- | tools/profile_example.txt | 5 |
2 files changed, 27 insertions, 4 deletions
diff --git a/tools/profile.py b/tools/profile.py index 796e2bf5..7961550a 100755 --- a/tools/profile.py +++ b/tools/profile.py @@ -162,9 +162,18 @@ BPF_STACK_TRACE(stack_traces, STACK_STORAGE_SIZE); // This code gets a bit complex. Probably not suitable for casual hacking. int do_perf_event(struct bpf_perf_event_data *ctx) { - u64 id = bpf_get_current_pid_tgid(); - u32 tgid = id >> 32; - u32 pid = id; + u32 tgid = 0; + u32 pid = 0; + + struct bpf_pidns_info ns = {}; + if (USE_PIDNS && !bpf_get_ns_current_pid_tgid(PIDNS_DEV, PIDNS_INO, &ns, sizeof(struct bpf_pidns_info))) { + tgid = ns.tgid; + pid = ns.pid; + } else { + u64 id = bpf_get_current_pid_tgid(); + tgid = id >> 32; + pid = id; + } if (IDLE_FILTER) return 0; @@ -216,6 +225,17 @@ int do_perf_event(struct bpf_perf_event_data *ctx) { } """ +# pid-namespace translation +try: + devinfo = os.stat("/proc/self/ns/pid") + bpf_text = bpf_text.replace('USE_PIDNS', "1") + bpf_text = bpf_text.replace('PIDNS_DEV', str(devinfo.st_dev)) + bpf_text = bpf_text.replace('PIDNS_INO', str(devinfo.st_ino)) +except: + bpf_text = bpf_text.replace('USE_PIDNS', "0") + bpf_text = bpf_text.replace('PIDNS_DEV', "0") + bpf_text = bpf_text.replace('PIDNS_INO', "0") + # set idle filter idle_filter = "pid == 0" if args.include_idle: diff --git a/tools/profile_example.txt b/tools/profile_example.txt index 65a10048..7dbc33af 100644 --- a/tools/profile_example.txt +++ b/tools/profile_example.txt @@ -154,7 +154,10 @@ Sampling at 49 Hertz of PID 25036 by user + kernel stack... Hit Ctrl-C to end. 7 Again, I've truncated some lines. Now we're just analyzing the dd process. -The filtering is performed in kernel context, for efficiency. +The filter is configured by specifying the target PID (from the current PID +namespace where we are profiling) via the "-p" flag. +Filtering is performed in kernel context, for efficiency, with automatic +PID translation to the top-level namespace (if required). This output has some "[unknown]" frames that probably have valid addresses, but we're lacking the symbol translation. This is a common for all profilers |