如何让 perf 脚本以文本而不是指针值的形式向系统调用显示字符串参数?
How to get perf script to show string args to system calls as text, not pointer values?
我正在尝试使用 perf 跟踪已删除的文件。我知道 eBPF / SystemTap 更适合这里,但我在工具选择 (ARM) 的平台上受限。
我是这样记录的
perf record -e 'syscalls:sys_enter_unlinkat'
用于报告
perf script -F +pid,+tid,-cpu
rm 15746/15746 7942.646974: syscalls:sys_enter_unlinkat: dfd: 0xffffff9c, pathname: 0x55a7960e6490, flag: 0x00000000
rm 15748/15748 7944.626120: syscalls:sys_enter_unlinkat: dfd: 0xffffff9c, pathname: 0x55dea122f490, flag: 0x00000000
rm 15750/15750 7947.111921: syscalls:sys_enter_unlinkat: dfd: 0xffffff9c, pathname: 0x55a515165490, flag: 0x00000000
如何获得类似于 strace 输出的字符串版本的 pathname
。
我还需要删除文件的进程的 uid。
在这种情况下,使用perf
工具将无法获得pathname
的字符串版本。
当用户空间实用程序调用 perf_even_open
系统调用并请求监视跟踪点事件时,例如您尝试使用 syscalls:sys_enter_unlinkat
监视的事件,一个 'perf probe' 函数附加到跟踪点。可以看到探测函数here.
探测函数分配一个perf buffer and validates the allocated buffer after which it invokes a bpf程序。
这个 bpf 程序需要知道静态跟踪点事件的 'format',因为它需要了解 perf 环形缓冲区中二进制跟踪输出的结构。
事件的格式在 /sys/kernel/debug/tracing/events/syscalls/sys_enter_unlinkat/format
文件中定义,适合您的情况。
如果您查看此文件,您会看到 perf script
根据字段中的 print fmt
条目报告输出。
name: sys_enter_unlinkat
ID: 722
format:
field:unsigned short common_type; offset:0; size:2; signed:0;
field:unsigned char common_flags; offset:2; size:1; signed:0;
field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
field:int common_pid; offset:4; size:4; signed:1;
field:int __syscall_nr; offset:8; size:4; signed:1;
field:int dfd; offset:16; size:8; signed:0;
field:const char * pathname; offset:24; size:8; signed:0;
field:int flag; offset:32; size:8; signed:0;
print fmt: "dfd: 0x%08lx, pathname: 0x%08lx, flag: 0x%08lx", ((unsigned long)(REC->dfd)), ((unsigned long)(REC->pathname)), ((unsigned long)(REC->flag))
perf
用户空间实用程序将始终遵守这种格式,不会偏离它。您可以从 this 提交中查看一些详细信息。
如果不对内核跟踪点进行真正广泛的修改 API,我看不到使用 perf
.
实现您想要的方法
如果您正在寻找的只是跟踪文件删除 activity 并且您想获得有关它的更多详细信息,我建议您尝试查看 fanotify.
我正在尝试使用 perf 跟踪已删除的文件。我知道 eBPF / SystemTap 更适合这里,但我在工具选择 (ARM) 的平台上受限。
我是这样记录的
perf record -e 'syscalls:sys_enter_unlinkat'
用于报告
perf script -F +pid,+tid,-cpu
rm 15746/15746 7942.646974: syscalls:sys_enter_unlinkat: dfd: 0xffffff9c, pathname: 0x55a7960e6490, flag: 0x00000000
rm 15748/15748 7944.626120: syscalls:sys_enter_unlinkat: dfd: 0xffffff9c, pathname: 0x55dea122f490, flag: 0x00000000
rm 15750/15750 7947.111921: syscalls:sys_enter_unlinkat: dfd: 0xffffff9c, pathname: 0x55a515165490, flag: 0x00000000
如何获得类似于 strace 输出的字符串版本的 pathname
。
我还需要删除文件的进程的 uid。
在这种情况下,使用perf
工具将无法获得pathname
的字符串版本。
当用户空间实用程序调用 perf_even_open
系统调用并请求监视跟踪点事件时,例如您尝试使用 syscalls:sys_enter_unlinkat
监视的事件,一个 'perf probe' 函数附加到跟踪点。可以看到探测函数here.
探测函数分配一个perf buffer and validates the allocated buffer after which it invokes a bpf程序。
这个 bpf 程序需要知道静态跟踪点事件的 'format',因为它需要了解 perf 环形缓冲区中二进制跟踪输出的结构。
事件的格式在 /sys/kernel/debug/tracing/events/syscalls/sys_enter_unlinkat/format
文件中定义,适合您的情况。
如果您查看此文件,您会看到 perf script
根据字段中的 print fmt
条目报告输出。
name: sys_enter_unlinkat
ID: 722
format:
field:unsigned short common_type; offset:0; size:2; signed:0;
field:unsigned char common_flags; offset:2; size:1; signed:0;
field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
field:int common_pid; offset:4; size:4; signed:1;
field:int __syscall_nr; offset:8; size:4; signed:1;
field:int dfd; offset:16; size:8; signed:0;
field:const char * pathname; offset:24; size:8; signed:0;
field:int flag; offset:32; size:8; signed:0;
print fmt: "dfd: 0x%08lx, pathname: 0x%08lx, flag: 0x%08lx", ((unsigned long)(REC->dfd)), ((unsigned long)(REC->pathname)), ((unsigned long)(REC->flag))
perf
用户空间实用程序将始终遵守这种格式,不会偏离它。您可以从 this 提交中查看一些详细信息。
如果不对内核跟踪点进行真正广泛的修改 API,我看不到使用 perf
.
如果您正在寻找的只是跟踪文件删除 activity 并且您想获得有关它的更多详细信息,我建议您尝试查看 fanotify.