Tracepoints 和 Kprobes 区别与故障排查

1. Tracepoints 与 Kprobes 的区别

tracepointskprobes 都是 Linux 内核提供的动态追踪机制,用于性能分析和调试。但它们有不同的设计理念和使用场景:

1.1 Tracepoints

适用场景:稳定性高,适用于长期维护的分析工具,如 eBPF、perf 采样、bpftrace 等。

官方提供的接口

  • tracepoints 由内核 显式 添加,代码中通常带有 TRACE_EVENT() 宏。

  • 这些点是 稳定 API,不会随内核版本轻易更改。

性能较优

  • 由于是 静态探测点,在编译时已经优化,性能损耗低。

  • 适用于高频事件(如 syscallsscheduler 调度等)。

使用方式

  • tracepoint 可以直接通过 /sys/kernel/debug/tracing/events/ 查询:

    ls /sys/kernel/debug/tracing/events/syscalls/
  • bpftrace 追踪 rename

    sudo bpftrace -e 'tracepoint:syscalls:sys_enter_rename { printf("rename detected\n"); }'

示例代码(使用 ``):

TRACEPOINT_PROBE(syscalls, sys_enter_rename) {

    
bpf_trace_printk("File rename detected: %s -> %s\n", args->oldpath, args->newpath);

    
return 0;

}

💡 适用场景

  • 系统调用跟踪syscallsblocknetsched 等)。

  • 稳定的 API,适用于生产环境。

  • 性能影响较低,适合长期运行。


1.2 Kprobes

适用场景:适用于深入分析和调试,灵活性强,但可能影响系统稳定性。

动态挂载

  • kprobes 可以挂载到任意内核函数,不需要提前定义探测点。

  • 适用于 调试私有/未公开的内核函数,如 do_renameat2

不稳定

  • kprobes 依赖 内核符号表,如果 内核更新,可能导致探测点失效或变化。

  • 生产环境慎用,可能影响系统稳定性。

使用方式

  • 列出可用 kprobes

    cat /sys/kernel/debug/tracing/available_filter_functions | grep rename
  • bpftrace 追踪 rename

    sudo bpftrace -e 'kprobe:sys_rename { printf("rename called\n"); }'

示例代码(使用 ``):

int trace_rename(struct pt_regs *ctx) {

    
bpf_trace_printk("sys_rename called!\n");

    
return 0;

}

💡 适用场景

  • 深入分析 内核函数(do_renameat2 等)。

  • 调试私有/不公开的内核函数

  • 用于开发调试,不建议长期运行,可能影响稳定性。


2. 主要区别总结

特性

Tracepoints

Kprobes

接口类型

静态(官方提供)

动态(用户自定义)

稳定性

(不会随内核版本变化)

(内核升级后可能失效)

性能

低开销(优化过的探测点)

可能较高(影响稳定性)

使用场景

系统调用、网络、调度、I/O

深入分析、调试私有内核函数

生产环境

可以长期使用

慎用,可能影响系统

示例

tracepoint:syscalls:sys_enter_rename

kprobe:sys_rename


3. 解决 错误

如果遇到错误:

Exception: Failed to attach BPF program b'trace_rename' to kprobe b'sys_rename'

说明 sys_rename 不存在或不可用,可能是被 sys_renameatsys_renameat2 取代。

3.1 检查可用相关函数

执行:

cat /sys/kernel/debug/tracing/available_filter_functions | grep rename

如果 sys_rename 不存在,请改用 sys_renameatsys_renameat2

3.2 自动适配可用系统调用

from bcc import BPF


bpf_text = """

int trace_rename(struct pt_regs *ctx) {

    
bpf_trace_printk("rename syscall triggered!\n");

    
return 0;

}

"""


bpf = BPF(text=bpf_text)


# 
适配不同的 
`rename` 
相关系统调用

for syscall in ["sys_rename", "sys_renameat", "sys_renameat2"]:

    
fnname = bpf.get_syscall_fnname(syscall)

    
if fnname:

        
print(f"Attaching to {fnname}...")

        
bpf.attach_kprobe(event=fnname, fn_name="trace_rename")


bpf.trace_print()

3.3 使用

from bcc import BPF


bpf_text = """

TRACEPOINT_PROBE(syscalls, sys_enter_rename) {

    
bpf_trace_printk("File rename detected!\n");

    
return 0;

}

"""

bpf = BPF(text=bpf_text)

bpf.trace_print()

4. 结论

  • 优先使用 tracepoints(如果可用)。

  • 如果 tracepoints 不存在,使用Kprobes 自动匹配

  • 长期监控用 tracepoints,调试用 kprobes


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

daolongzhang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值