http://gmd20.blog.163.com/blog/static/168439232015475525227/

 
 
 
 
 
 

用systemtap跟踪打印动态链接库的所有c++函数调用过程
=================================================

1. ltrace 的问题
---------------
用ltrace 可以打印所有的so文件调用了。但上次试过如果so是自己用dlopen来加载的。
就是在elf结构里面没有对应的依赖项的情况下,ltrace好像是没有做对应的调用了。
用systemtap的就没有这个问题,打印输出也更灵活一些。

2. systemtap的解析c++ 函数问题
------------------------------
systemtap的 probe point 指定函数名,是支持c++ 方式指定名字的。
但默认的打印输出却只能输出函数名,不包含c++ 类名。

c++ 的函数符号是经过修饰的,比如用 nm *.so 查看就可以看到 _Z开头一大堆函数名字。

# c++filt _ZZN9log4cplus19initializeLog4cplusEvE11initialized
log4cplus::initializeLog4cplus()::initialized

systemtap的 ppfunc () 函数只输出"initialized"
systemtap的 probefunc () 函数输出 "_ZZN9log4cplus19initializeLog4cplusEvE11initialized"
其实我们想要的是 “log4cplus::initializeLog4cplus()::initialized”
但看一下文件是没有这个tapset函数的,估计的自己写一个才行。

还好有c++filt 这个命令,可以做c++ 函数名的demangle。 我们就可以简单用probefunc 打印
然后在自己用c++filt 命令来转换一下好了。

3. systemtap的函数调用跟踪
---------------------------
systemtap的资料就有一个 para-callgraph.stp ,根据自己的要求做修改吧。

我是这样用的,打印所有libTest.so 源码文件 *.hpp *.cpp 的所有函数,
也就是只有c++的函数。 其实用来跟踪c函数调用那些用起来更好用吧,都不用做c++
函数名转换了。根据自己要求来设置跟踪哪些函数吧。
stap para-callgraph.stp 'process("/usr/lib/libTest.so").function("*@*pp")' 'process("/usr/lib/libTest.so").function("Init")' > trace_file.txt

```
#! /usr/bin/env stap

function trace(entry_p, extra) {
/* %( $# > 1 %? if (tid() in trace) %) */
%( $# > 1 %? if (2 > 1) %)
printf("%s%s%s %s\n",
thread_indent (entry_p),
(entry_p>0?"->":"<-"),
/* ppfunc (), 只有函数名,没有包含类名*/
probefunc (),
extra)
}

%( $# > 1 %?
global trace
probe $2.call {
trace[tid()] = 1
}
probe $2.return {
delete trace[tid()]
}
%)

probe $1.call { trace(1, $$parms) }
probe $1.return { trace(-1, $$return) }

// 第一个参数是跟踪的打印的函数,第二个参数是触发记录的函数。
// https://sourceware.org/systemtap/langref/Probe_points.html#SECTION00051300000000000000
// probe_point = <function name@filename:line_number>
// stap para-callgraph.stp 'kernel.function("*@fs/*.c")' 'kernel.function("sys_read")':
// stap para-callgraph.stp 'process("/usr/lib/libtest.so").function("*")' 'process("/usr/lib/libtest.so").function("TestInit")'
// stap para-callgraph.stp 'process("/usr/lib/libtest.so").function("*@*cpp")' 'process("/usr/lib/libtest.so").function("TestInit")'
// stap para-callgraph.stp 'process("/usr/lib/libtest.so").function("*@*cpp:*")' 'process("/usr/lib/libtest.so").function("TestInit")'
// stap para-callgraph.stp 'process("/usr/lib/libtest.so").function("*@*cpp:1-200")' 'process("/usr/lib/libtest.so").function("TestInit")'

```

4. 写个简单的perl脚本来调用c++filt 来做函数名转换
----------------------------------------------

```
#!/usr/bin/perl -w
use strict;

open(INFILE, "trace_file.txt");
open(OUTFILE, ">trace_file_2.txt");

my $line;
while ($line = <INFILE>){
if ($line =~ /boost|Trace/) {
next;
}
if ($line =~ /(.*)(_Z\S+)(.*)/) {
my $function_name = `c++filt $2`;

chomp($function_name);
print OUTFILE $1, $function_name, $3, "\n";
} else {
print OUTFILE $line;
}
}

close INFILE;
close OUTFILE;

用systemtap跟踪打印动态链接库的所有c++函数调用过程的更多相关文章

  1. 20135202闫佳歆--week 8 实验:理解进程调度时机跟踪分析进程调度与进程切换的过程--实验及总结

    week 8 实验:理解进程调度时机跟踪分析进程调度与进程切换的过程 1.环境搭建: rm menu -rf git clone https://github.com/megnning/menu.gi ...

  2. 理解进程调度时机跟踪分析进程调度与进程切换的过程(Linux)

    ----------------------------------------------------------------------------------- 理解进程调度时机跟踪分析进程调度 ...

  3. mdl 锁 SYSTEMTAP跟踪

    systemtap : 各种资源的使用限制由所生成的C代码中的宏来设置.这些值可在编译时由-D选项来重写.下面描述了部分挑选出来的宏: MAXNESTING 递归函数的最大调用层数,默认值是10. M ...

  4. sync fsync fdatasync ---systemtap跟踪

    aa.stp: probe kernel .function ( "sys_sync" ) { printf ( "probfunc:%s fun:%s\n", ...

  5. systemtap跟踪C

    1.[root@localhost ~]# rpm -qi  glibcName        : glibc                        Relocations: (not rel ...

  6. Linux内核分析之理解进程调度时机跟踪分析进程调度与进程切换的过程

    一.原理分析 1.调度时机 背景不同类型的进程有不同的调度需求第一种分类I/O-bond:频繁的进行I/O:通常会花费很多时间等待I/O操作的完成CPU-bound:计算密集型:需要大量的CPU时间进 ...

  7. 通过gdb跟踪Linux内核装载和启动可执行程序过程

    作者:吴乐 山东师范大学 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 实验目的:通过对一个简单的可执 ...

  8. 【实习记】2014-08-10(上)代码跟踪git的想法+归并排序的debug过程

        (冒泡,选择,插入,希尔,快速,归并,堆排)周末加班学习C++,打算用C++写七大经典排序代码.发现3个月前自己写的七大经典排序代码(C Language)突然运行出错. Makefile内容 ...

  9. (转)logback 打印Mybitis中的sql执行过程

    场景:在程序开发过程中经常需要跟踪程序中sql语句的执行过程,在控制台打印出sql语句和对应的参数传递就能够更快的定位错误! 原文出处:http://www.cnblogs.com/beiyeren/ ...

随机推荐

  1. ios面试题(三)

    4.写一个setter方法用于完成@property (nonatomic,retain)NSString *name,写一个setter方法用于完成@property(nonatomic,copy) ...

  2. redo log日志内容备忘

    检查点是一串递增的数字. 在两个检查点之间,存在有一个MLOG_FILE_NAME的文件,里面记录着space和路径和MLOG_CHECKPOINT的一个检查点. MLOG_FILE_NAME总是在上 ...

  3. Linux用户身份(命令详解与补正)

    基于Red Hat Enterprise Linux 7.5 Linux中的root就是存在于所有类UNIX系统中的超级用户,持有最高管理权限,能添加/删除用户.开关机.关闭或开启硬件或者系统服务等, ...

  4. 网络设备之ospf2

    OSPF(Open Shortest Pass First,开放最短路径优先协议),是一个最常用的内部网管协议,是一个链路状态协议. OSPF的特点 OSPF是一种无类路由协议,支持VLSM可变长子网 ...

  5. node.js中常用的fs文件系统

    fs文件系统模块对于系统文件及目录进行一些读写操作. 模块中的方法均有异步和同步版本,例如读取文件内容的函数有异步的 fs.readFile() 和同步的 fs.readFileSync(). 异步的 ...

  6. PyQt5(2)、垃圾分类小程序(2)——初代窗口程序可执行文件

    又是一天时间(又没做大作业).今天的心路历程:(1)前端后端怎么连接?(2)后端数据库插数据(3)完全没用上之前的字典反查法(4)突然发现面向对象编程其实很好用,甚至越用越上瘾(5)QLineEdit ...

  7. One-to-one

    创建模型 在本例中,Place 和 Restaurant 为一对一关系 from django.db import models class Place(models.Model): name = m ...

  8. 基于IAR移植sdk12.2.0建立nrf52832的工程———GPIO

    工程伊始,需要在sdk包中拷贝三个重要的文件,blinky_iar_nRF5x.icf,iar_startup_nrf52.s,system_nrf52.c. 工程目录建立: 1.建立bsp文件,包括 ...

  9. python基础学习笔记——生成器与推导式

    生成器 首先我们来看看什么是个生成器,生成器本质就是迭代器 在python中有三种方式来获取生成器 1.通过生成器函数 2.通过各种推到式来实现生成器 3.通过数据的转换也可以获取生成器 首先,我们先 ...

  10. 三、harbor部署之SSL

    1 签名证书与自签名证书 签名证书:由权威颁发机构颁发给服务器或者个人用于证明自己身份的东西. 自签名证书:由服务器自己颁发给自己,用于证明自己身份的东西,非权威颁发机构发布. 2 openssl简介 ...