aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuca Bruno <lucab@lucabruno.net>2023-08-31 13:46:16 +0200
committerGitHub <noreply@github.com>2023-08-31 07:46:16 -0400
commit442f658dc22d70bb024cac448932e27090d4a965 (patch)
treea851184c61198559c275871a6be296f5120b4fe1
parent9596edb9415197aa52d771b65581a73b89f3f4dc (diff)
downloadbcc-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-xtools/profile.py26
-rw-r--r--tools/profile_example.txt5
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