Search code examples
linuxarmembeddedperf

How to get perf script to show string args to system calls as text, not pointer values?


I am attempting to track deleted files with perf. I know eBPF / SystemTap is better suited here, but I am limited on the platform with tool choices (ARM).

This is how I am recording it

perf record -e 'syscalls:sys_enter_unlinkat'

For reporting

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

How do I get string version of pathname as similar to that of strace output. I also need uid of the process that deleted the file.


Solution

  • It will not be possible to obtain the string version of pathname using perf tools in this case.

    When a userspace utility calls perf_even_open syscall with a request to monitor tracepoint events, such as the one you are trying to monitor with syscalls:sys_enter_unlinkat, a 'perf probe' function is attached to the tracepoint. You can see the probe function here.

    The probe function allocates a perf buffer and validates the allocated buffer after which it invokes a bpf program.

    This bpf program needs to know the 'format' of the static tracepoint event, since it needs to understand what is the structure of the binary trace output in the perf ring buffer.

    The format of the event is defined in the /sys/kernel/debug/tracing/events/syscalls/sys_enter_unlinkat/format file, for your case.

    If you look at this file, you will see that perf script reports the output as per the print fmt entry in the field.

    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))
    

    The perf userspace utility will always adhere to this format and will not deviate from it. You can see some details from this commit.

    Without a really extensive modification to the kernel tracepoint API, I do not see a way to achieve what you want using perf.

    If all you are looking for is to track file deletion activity and you want to get additional details about it, I would suggest you try and take a look at fanotify.