bpftrace的使用网上没有太多的说明;皮毛都算不上,都是介绍这个东西是啥,连个有用的实例也没有,没有啥参考意义,不如直接看看官方的文档;
我这里给一个干货,比如你的程序调用了libcurl访问网页,检测一下用了多久;
bt监控脚本教程见官方:bpftrace/reference_guide.md at master · iovisor/bpftrace · GitHub
脚本如下:(保存为 t.bt )
BEGIN
{
@start = nsecs;
}
uprobe:/lib/x86_64-linux-gnu/libcurl.so.4:curl_easy_setopt
{
if (arg1 == 10002)
{
printf("seturl pid=%d, tid=%d, url=%s\n", pid, tid, str(arg2));
}
}
uprobe:/lib/x86_64-linux-gnu/libcurl.so.4:curl_easy_perform
{
printf("enter pid=%d, tid=%d, process=%s\n", pid, tid, comm);
@start = nsecs;
}
uretprobe:/lib/x86_64-linux-gnu/libcurl.so.4:curl_easy_perform
{
printf("finish pid=%d, tid=%d, cost=%d ms\n", pid, tid, (nsecs - @start)/1000000);
}
使用过程中,需要注意的是:
1)对监控的进程需要执行ldd查看动态库所在的路径,而不是直接写进程可执行程序路径:
ldd exe_name
2)curl设置url中的参数,需要根据第2个参数来判断;
另一个bash窗口启动需要监控的进程,此窗口执行脚本等待输出;
输出的结果为:
备注:题外话,在c++的程序编译后,我们见到的符号名字(ABI)不一定是原来的样子,只有C风格的接口才会保持原来的样子,那么改如何对应原来的的名字呢?答案是使用c++filt工具,翻译程序中的符号的命令如下:
nm -l icmp | grep "Icmp" | c++filt
1)icmp是我写的程序名;
2)Icmp是其中的类名,过滤相关的类,
可以看到原来的名字,这样我们就可以将监控的符号名与原始名字对应起来了;
输出如下:
00000000000375a8 T IcmpWorker::preSortUrl(std::shared_ptr<oneapm::Info>&) /robin1/ct_agent/src/IcmpWorker.cpp:173
00000000000372d4 T IcmpWorker::curl(std::shared_ptr<oneapm::Info>&) /robin1/ct_agent/src/IcmpWorker.cpp:145
0000000000036bd8 T IcmpWorker::init() /robin1/ct_agent/src/IcmpWorker.cpp:14
0000000000036c00 T IcmpWorker::ping(std::shared_ptr<oneapm::Info>&, int) /robin1/ct_agent/src/IcmpWorker.cpp:21
0000000000036f88 T IcmpWorker::trace(std::shared_ptr<oneapm::Info>&) /robin1/ct_agent/src/IcmpWorker.cpp:83
0000000000037a54 T IcmpWorker::doWork(std::shared_ptr<oneapm::Info>&) /robin1/ct_agent/src/IcmpWorker.cpp:238
0000000000036afe T IcmpWorker::IcmpWorker() /robin1/ct_agent/src/IcmpWorker.cpp:5
0000000000036afe T IcmpWorker::IcmpWorker() /robin1/ct_agent/src/IcmpWorker.cpp:5
0000000000036bae T IcmpWorker::~IcmpWorker() /robin1/ct_agent/src/IcmpWorker.cpp:9
0000000000036b6a T IcmpWorker::~IcmpWorker() /robin1/ct_agent/src/IcmpWorker.cpp:9
0000000000036b6a T IcmpWorker::~IcmpWorker() /robin1/ct_agent/src/IcmpWorker.cpp:9
但是,在c++中获取参数更加麻烦,主要是因为参数很多并非基础类型或者基础类型指针,有可能是类的引用,比如某成员函数如下:
void Icmp::executeTask(string & name, Task & task)
{
}
这个,我也没有想明白怎么提取呢,如果你知道,希望也告诉我。
待续……