将 bpf 附加到 sys_enter(可通过 /proc/kallsyms 获得跟踪点)
attaching bpf to sys_enter (tracepoint available through /proc/kallsyms)
我正在尝试构建一个工具,其中我将 BPF 程序附加到所有系统调用的入口点。从 CLI,我能够通过
附加到所有系统调用条目
sudo bpftrace -e 'tracepoint:syscalls:sys_enter_* /comm != "bpftrace"/ {printf("Process Name: %s\nSyscall Requested: %s\n", comm, probe);}'
这很好,但我想做更复杂的事情。我发现我可以使用 python 的前端将 BPF 程序附加到 kprobe 事件 --
#!/usr/bin/python
from bcc import BPF
prog = """
int hello(void *ctx){
bpf_trace_printk("Hello, world!\n");
return 0;
}
"""
b = BPF(text=prog)
b.attach_kprobe(event="__x64_sys_clone", fn_name="hello)
print("TIME(s)", "COMM", "PID", "MESSAGE")
while 1:
try:
(task, pid, cpu, flags, ts, msg) = b.trace_fields()
except ValueError:
continue
except KeyboardInterrupt:
exit()
printb(b"%-18.9f %-16s %-6d %s" %(ts, task, pid, msg))
但是,在 attach_kprobe 行中我想附加到所有系统调用条目而不是 sys_clone。我在 /sys/kernel/debug/tracing/available_filter_functions
中没有找到任何 sys_enter 跟踪点,但是,我在 /proc/kallsyms
中找到了 __tracepoint_sys_enter。但是,当我尝试将 __x64_sys_clone 替换为 __tracepoint_sys_enter 时,出现无效参数错误。我想知道,我可以使用 kprobes 附加到所有系统调用条目(并最终退出)吗?或者我是否需要使用不同的跟踪机制。谢谢!
我认为没有办法通过 BPF 使用单个 kprobe 附加点跟踪所有系统调用。相反,您可以做的是从给定模式(即 sys_enter_*
)导出所有匹配的 krprobe 钩子的列表。
在 bcc 中,有一个 函数叫做 BPF.get_kprobe_functions()
that allows you to do just that. You can see an example usage in bcc's funccount.py
。我猜 bpftrace 在给它一个模式时会做一些非常相似的事情。
似乎没有捕获所有系统调用入口点的 kprobes 事件——相反,似乎每个系统调用入口都有一个 kprobe 事件。虽然我们可以通过应用于每个 kprobe 系统调用入口事件(具体来说,通过使用 pchaigno 概述的方法)来编写所需的逻辑,但我们可以通过附加到单个 TRACEPOINT 事件来实现同样的目的 --
from bcc import BPF
b = BPF(text = """
TRACEPOINT_PROBE(raw syscalls, sys_enter)
{
bpf_trace_printk("Hello world\n");
}
""")
while 1:
try:
(task, pid, cpu, flags, ts, msg) = b.trace_fields()
except ValueError:
continue
print("%-18.9f %-16s %-6d %s" % (ts, task, pid, msg))
同样,我们可以附加到所有系统调用出口点
我正在尝试构建一个工具,其中我将 BPF 程序附加到所有系统调用的入口点。从 CLI,我能够通过
附加到所有系统调用条目sudo bpftrace -e 'tracepoint:syscalls:sys_enter_* /comm != "bpftrace"/ {printf("Process Name: %s\nSyscall Requested: %s\n", comm, probe);}'
这很好,但我想做更复杂的事情。我发现我可以使用 python 的前端将 BPF 程序附加到 kprobe 事件 --
#!/usr/bin/python
from bcc import BPF
prog = """
int hello(void *ctx){
bpf_trace_printk("Hello, world!\n");
return 0;
}
"""
b = BPF(text=prog)
b.attach_kprobe(event="__x64_sys_clone", fn_name="hello)
print("TIME(s)", "COMM", "PID", "MESSAGE")
while 1:
try:
(task, pid, cpu, flags, ts, msg) = b.trace_fields()
except ValueError:
continue
except KeyboardInterrupt:
exit()
printb(b"%-18.9f %-16s %-6d %s" %(ts, task, pid, msg))
但是,在 attach_kprobe 行中我想附加到所有系统调用条目而不是 sys_clone。我在 /sys/kernel/debug/tracing/available_filter_functions
中没有找到任何 sys_enter 跟踪点,但是,我在 /proc/kallsyms
中找到了 __tracepoint_sys_enter。但是,当我尝试将 __x64_sys_clone 替换为 __tracepoint_sys_enter 时,出现无效参数错误。我想知道,我可以使用 kprobes 附加到所有系统调用条目(并最终退出)吗?或者我是否需要使用不同的跟踪机制。谢谢!
我认为没有办法通过 BPF 使用单个 kprobe 附加点跟踪所有系统调用。相反,您可以做的是从给定模式(即 sys_enter_*
)导出所有匹配的 krprobe 钩子的列表。
在 bcc 中,有一个 函数叫做 BPF.get_kprobe_functions()
that allows you to do just that. You can see an example usage in bcc's funccount.py
。我猜 bpftrace 在给它一个模式时会做一些非常相似的事情。
似乎没有捕获所有系统调用入口点的 kprobes 事件——相反,似乎每个系统调用入口都有一个 kprobe 事件。虽然我们可以通过应用于每个 kprobe 系统调用入口事件(具体来说,通过使用 pchaigno 概述的方法)来编写所需的逻辑,但我们可以通过附加到单个 TRACEPOINT 事件来实现同样的目的 --
from bcc import BPF
b = BPF(text = """
TRACEPOINT_PROBE(raw syscalls, sys_enter)
{
bpf_trace_printk("Hello world\n");
}
""")
while 1:
try:
(task, pid, cpu, flags, ts, msg) = b.trace_fields()
except ValueError:
continue
print("%-18.9f %-16s %-6d %s" % (ts, task, pid, msg))
同样,我们可以附加到所有系统调用出口点