首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在Linux中使用USDT探针(Dtrace)的BPF程序

在Linux中使用USDT探针(Dtrace)的BPF程序
EN

Stack Overflow用户
提问于 2020-06-29 15:31:41
回答 1查看 877关注 0票数 3

因此,我遵循这个链接将一个BPF程序附加到用户空间探测( Dtrace )(参见用户静态定义的跟踪点一节)。

C程序:

代码语言:javascript
运行
复制
#include <sys/sdt.h>
int main() {
    DTRACE_PROBE("hello-usdt", "probe-main");
}

检查以确保探测信息包括:

代码语言:javascript
运行
复制
readelf -n hello_usdt
  stapsdt              0x00000033   NT_STAPSDT (SystemTap probe descriptors)
    Provider: "hello_usdt"
    Name: "probe-main"
    Location: 0x0000000000400535, Base: 0x00000000004005d4, Semaphore: 0x0000000000000000
    Arguments: 

也是用tplist:

代码语言:javascript
运行
复制
sudo /usr/share/bcc/tools/tplist -l /path/to/hello_usdt
/path/to/hello_usdt "hello_usdt":"probe-main"

BPF程序(usdt.py)的内容:

代码语言:javascript
运行
复制
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();
  bpf_trace_printk("New hello_usdt process running with PID: %d", pid);
}
"""

usdt = USDT(path = "./hello_usdt")
usdt.enable_probe(probe = "probe-main", fn_name = "trace_binary_exec")
bpf = BPF(text = bpf_source, usdt = usdt)
bpf.trace_print()

故障描述:

代码语言:javascript
运行
复制
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

我也尝试过:

  1. 在BPF程序中给出完整的可执行文件(hello_usdt):

usdt = USDT(path = "/full/path/to/hello_usdt")

  1. 将上面的行替换为PID值(./hello_usdt &),在BPF程序中直接获取pid:

usdt = USDT(pid=1234)

  1. 在安装python2.7软件包后,使用python2.7和3.7进行了尝试。

到目前为止还没有运气。任何帮助都很感激。谢谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-06-29 20:17:35

我想我弄清楚了原来的链接有什么问题。我修补了bcc-tools (函数bcc_usdt_enable_probe和更深)的源文件,用一些printfs编译并安装了这个自定义版本,以跟踪失败的原因。结果发现,在解析探测列表时,我的程序中定义的探测被视为带有附加引号的字符串,类似于“探测-主”。所以我换了台词:

代码语言:javascript
运行
复制
DTRACE_PROBE("hello-usdt", "probe-main");

使用

代码语言:javascript
运行
复制
DTRACE_PROBE("hello-usdt", probe-main);

我做的第二个改变是在python脚本中。我没有详细说明,但这一行看起来是错误的(语法):

代码语言:javascript
运行
复制
bpf = BPF(text = bpf_source, usdt = usdt)

python编译器抱怨usdt不为人所知,我找到了其他使用的实现。因此,我将上面的一行替换为:

代码语言:javascript
运行
复制
bpf = BPF(text = bpf_source, usdt_contexts = [usdt])

然后在源代码中替换另一个探测宏,以包括一个额外的时间戳:

代码语言:javascript
运行
复制
DTRACE_PROBE1("hello_usdt", probe-main, tv.tv_sec);

还更新了python脚本:

代码语言:javascript
运行
复制
#!/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()

让它运行起来:

代码语言:javascript
运行
复制
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'

我不知道为什么原始链接中的实现是不同的。也许是BPF/Dtrace版本的问题,没有详细说明。然而,我没有找到涵盖基本C程序所有步骤的其他实现,而是找到了帮助我解决这个问题的代码片段。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62641551

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档