Linux下BPF程序结合USDT(Dtrace格式)探针调试失败求助
看起来你在挂载BPF到Dtrace格式USDT探针时遇到了典型的匹配或加载时机问题,我来帮你梳理下可行的解决方向:
1. 确认Provider名称的一致性
你提到C代码里用的是DTRACE_PROBE("hello-usdt", "probe-main"),但tplist识别到的Provider是hello_usdt(下划线替代了连字符)——这是部分系统的自动转换行为:USDT探针的Provider名称中的特殊字符会被替换为下划线。
你需要在enable_probe时显式指定正确的Provider名称,修改Python代码:
# 注意provider要和tplist输出的一致,比如是hello_usdt还是hello-usdt usdt.enable_probe(probe="probe-main", fn_name="trace_binary_exec", provider="hello_usdt")
如果不确定具体名称,用bpftrace先列出所有可用探针:
sudo bpftrace -l 'usdt:/path/to/hello_usdt:*'
输出格式为usdt:<path>:<provider>:<probe>,直接取用其中的provider名称即可。
2. 确保程序启动时机正确
当用USDT(path="./hello_usdt")初始化时,BCC会预加载二进制文件,但探针只有在目标进程运行时才会触发。正确操作流程:
- 先启动BPF脚本
sudo ./usdt.py,让它处于等待状态 - 打开另一个终端,运行目标程序
./hello_usdt
如果脚本直接报错找不到探针,可改用动态PID方式:
- 先修改C代码,在探针后加
sleep(60)让进程保持运行,编译后启动./hello_usdt - 用
pgrep hello_usdt获取进程PID - 修改Python代码:
usdt = USDT(pid=1234)(替换为实际PID),再运行脚本
3. 检查编译环节是否正确
编译带USDT探针的C程序时,部分系统需要显式链接sdt库,否则探针可能无法正确生成:
gcc -o hello_usdt hello_usdt.c -lsdt
重新编译后用readelf -n再次验证探针描述符是否存在。
4. 开启BCC调试日志排查细节
如果以上方法都无效,开启BCC调试模式获取更详细的错误信息:
sudo BCC_DEBUG=1 ./usdt.py
日志会展示USDT探针的查找、加载全过程,帮你定位是文件路径错误、权限问题还是匹配失败。
5. 用bpftrace验证探针可用性
先脱离BCC环境,用bpftrace测试探针是否能正常触发:
sudo bpftrace -e 'usdt:/path/to/hello_usdt:hello_usdt:probe-main { printf("Probe triggered! PID: %d\\n", pid); }'
运行目标程序后,如果bpftrace能输出信息,说明探针本身没问题,问题出在BCC脚本的配置上;如果bpftrace也捕获不到,就要重新检查C程序的探针定义和编译流程了。
内容的提问来源于stack exchange,提问作者mdaniel

