mda*_*iel 5 linux dtrace probe bpf ebpf
因此,我按照此链接将 BPF 程序附加到用户空间探针,Dtrace 格式(请参阅用户静态定义的跟踪点部分)。
C程序:
#include <sys/sdt.h>
int main() {
DTRACE_PROBE("hello-usdt", "probe-main");
}
Run Code Online (Sandbox Code Playgroud)
确保包含探测信息的检查:
readelf -n hello_usdt
stapsdt 0x00000033 NT_STAPSDT (SystemTap probe descriptors)
Provider: "hello_usdt"
Name: "probe-main"
Location: 0x0000000000400535, Base: 0x00000000004005d4, Semaphore: 0x0000000000000000
Arguments:
Run Code Online (Sandbox Code Playgroud)
还有 tplist:
sudo /usr/share/bcc/tools/tplist -l /path/to/hello_usdt
/path/to/hello_usdt "hello_usdt":"probe-main"
Run Code Online (Sandbox Code Playgroud)
BPF程序的内容(usdt.py):
readelf -n hello_usdt
stapsdt 0x00000033 NT_STAPSDT (SystemTap probe descriptors)
Provider: "hello_usdt"
Name: "probe-main"
Location: 0x0000000000400535, Base: 0x00000000004005d4, Semaphore: 0x0000000000000000
Arguments:
Run Code Online (Sandbox Code Playgroud)
故障描述:
sudo ./usdt.py
Traceback (most recent call last):
File "./usdt.py", line 13, in <module>
usdt.enable_probe(probe = "probe-main", fn_name = "trace_binary_exec")
File "/usr/lib/python3/dist-packages/bcc/usdt.py", line 154, in enable_probe
probe
bcc.usdt.USDTException: failed to enable probe 'probe-main';
a possible cause can be that the probe requires a pid to enable
Run Code Online (Sandbox Code Playgroud)
我也尝试过:
usdt = USDT(path = "/full/path/to/hello_usdt")
usdt = USDT(pid=1234)
到目前为止还没有运气。非常感谢任何帮助。谢谢。
我想我知道原始链接出了什么问题。我修补了 bcc-tools 的源文件(函数 bcc_usdt_enable_probe 和更深层次),使用一些 printfs 编译并安装了这个自定义版本,以跟踪它失败的原因,结果发现,在解析探针列表时,我的程序中定义的探针被视为带有附加引号的字符串,如下所示:“”probe-main“”。所以我更换了该行:
DTRACE_PROBE("hello-usdt", "probe-main");
Run Code Online (Sandbox Code Playgroud)
和
DTRACE_PROBE("hello-usdt", probe-main);
Run Code Online (Sandbox Code Playgroud)
我做的第二个更改是在 python 脚本中。我没有详细说明,但看起来这一行是错误的(语法):
bpf = BPF(text = bpf_source, usdt = usdt)
Run Code Online (Sandbox Code Playgroud)
python编译器抱怨usdt未知,然后我发现使用usdt_contexts=[usdt]的其他实现。所以我将上面的行替换为:
bpf = BPF(text = bpf_source, usdt_contexts = [usdt])
Run Code Online (Sandbox Code Playgroud)
然后在源代码中替换探针宏以包含附加时间戳:
DTRACE_PROBE1("hello_usdt", probe-main, tv.tv_sec);
Run Code Online (Sandbox Code Playgroud)
还更新了 python 脚本:
#!/usr/bin/python3
from bcc import BPF, USDT
bpf_source = """
#include <uapi/linux/ptrace.h>
int trace_binary_exec(struct pt_regs *ctx) {
u64 pid = bpf_get_current_pid_tgid();
u64 ts=0;
bpf_usdt_readarg(1, ctx, &ts);
bpf_trace_printk("PROBE-HIT (PID: %d), TS: %lu\\n", pid, ts);
}
"""
usdt = USDT(path = "/path/to/hello_usdt")
usdt.enable_probe(probe = "probe-main", fn_name = "trace_binary_exec")
bpf = BPF(text = bpf_source, usdt_contexts = [usdt])
bpf.trace_print()
Run Code Online (Sandbox Code Playgroud)
并让它运行:
sudo ./usdt.py
b' hello_usdt-18920 [000] .... 300066.568941: 0x00000001: PROBE-HIT (PID: 18920), TS: 1593460390'
b' hello_usdt-18920 [000] .... 300067.569284: 0x00000001: PROBE-HIT (PID: 18920), TS: 1593460391'
b' hello_usdt-18920 [000] .... 300068.569509: 0x00000001: PROBE-HIT (PID: 18920), TS: 1593460392'
b' hello_usdt-18920 [000] .... 300069.569935: 0x00000001: PROBE-HIT (PID: 18920), TS: 1593460393'
b' hello_usdt-18920 [000] .... 300070.570362: 0x00000001: PROBE-HIT (PID: 18920), TS: 1593460394'
b' hello_usdt-18920 [000] .... 300083.574478: 0x00000001: PROBE-HIT (PID: 18920), TS: 1593460407'
b' hello_usdt-18920 [000] .... 300084.574782: 0x00000001: PROBE-HIT (PID: 18920), TS: 1593460408'
b' hello_usdt-18920 [000] .... 300085.575214: 0x00000001: PROBE-HIT (PID: 18920), TS: 1593460409'
b' hello_usdt-18920 [000] .... 300086.575630: 0x00000001: PROBE-HIT (PID: 18920), TS: 1593460410'
Run Code Online (Sandbox Code Playgroud)
我不知道为什么原始链接中的实现不同。可能是BPF/Dtrace版本的问题,就不详细说了。然而,我没有找到涵盖基本 C 程序所有步骤的其他实现,但找到了帮助我解决问题的代码片段。