用systemtap跟踪打印动态链接库的所有c++函数调用过程
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++函数调用过程的更多相关文章
- 20135202闫佳歆--week 8 实验:理解进程调度时机跟踪分析进程调度与进程切换的过程--实验及总结
week 8 实验:理解进程调度时机跟踪分析进程调度与进程切换的过程 1.环境搭建: rm menu -rf git clone https://github.com/megnning/menu.gi ...
- 理解进程调度时机跟踪分析进程调度与进程切换的过程(Linux)
----------------------------------------------------------------------------------- 理解进程调度时机跟踪分析进程调度 ...
- mdl 锁 SYSTEMTAP跟踪
systemtap : 各种资源的使用限制由所生成的C代码中的宏来设置.这些值可在编译时由-D选项来重写.下面描述了部分挑选出来的宏: MAXNESTING 递归函数的最大调用层数,默认值是10. M ...
- sync fsync fdatasync ---systemtap跟踪
aa.stp: probe kernel .function ( "sys_sync" ) { printf ( "probfunc:%s fun:%s\n", ...
- systemtap跟踪C
1.[root@localhost ~]# rpm -qi glibcName : glibc Relocations: (not rel ...
- Linux内核分析之理解进程调度时机跟踪分析进程调度与进程切换的过程
一.原理分析 1.调度时机 背景不同类型的进程有不同的调度需求第一种分类I/O-bond:频繁的进行I/O:通常会花费很多时间等待I/O操作的完成CPU-bound:计算密集型:需要大量的CPU时间进 ...
- 通过gdb跟踪Linux内核装载和启动可执行程序过程
作者:吴乐 山东师范大学 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 实验目的:通过对一个简单的可执 ...
- 【实习记】2014-08-10(上)代码跟踪git的想法+归并排序的debug过程
(冒泡,选择,插入,希尔,快速,归并,堆排)周末加班学习C++,打算用C++写七大经典排序代码.发现3个月前自己写的七大经典排序代码(C Language)突然运行出错. Makefile内容 ...
- (转)logback 打印Mybitis中的sql执行过程
场景:在程序开发过程中经常需要跟踪程序中sql语句的执行过程,在控制台打印出sql语句和对应的参数传递就能够更快的定位错误! 原文出处:http://www.cnblogs.com/beiyeren/ ...
随机推荐
- 看结果,测试?java中的String类 字符串拆分成字符串数组 判定邮箱地址 字符串比较 参数传递?
看结果1? package com.swift; class ArrayString { public static void main(String[] args) { String str = & ...
- centOS下SVN安装和配置
1>SVN服务器端文件可见问题 在平时使用SVN时候,一直以为在客户提交文件,那么在服务器对应的版本库下面就会有相同文件.在自己搭建后,发现提交到服务器端文件完全看不见.... 这是由于SVN服 ...
- Git学习——提交BUG
git stash 可以把当前工作区的修改存储起来,此时可以查看工作区是干净的.这时可以切换到别的分支去处理BUG.等BUG处理好之后,回到该分支,恢复工作区.通过: git stash list 查 ...
- java代码解析二维码
java代码解析二维码一般步骤 本文采用的是google的zxing技术进行解析二维码技术,解析二维码的一般步骤如下: 一.下载zxing-core的jar包: 二.创建一个BufferedImage ...
- 身为前端开发工程师,你需要了解的搜索引擎优化SEO.
网站url网站创建具有良好描述性.规范.简单的url,有利于用户更方便的记忆和判断网页的内容,也有利于搜索引擎更有效的抓取您的网站.网站设计之初,就应该有合理的url规划. 处理方式: 1.在系统中只 ...
- [php] 表单注意事项
什么是 htmlspecialchars()方法? htmlspecialchars() 函数把一些预定义的字符转换为 HTML 实体. 预定义的字符是: & (和号) 成为 & &q ...
- 【php】 get 和 post 比较
来源 php.net 评论区 -- nucc1 worth clarifying: POST is not more secure than GET. The reasons for choosing ...
- 关于在一台主机上安装2个不同版本的Oracle服务端
一.安装Oracle12c 按正常安装方法安装即可! ORACLE_BASE=/u01/app ORACLE_HOME=/u01/app/oracle ORACLE_SID=a4orcl 二.安装Or ...
- 16,re模块的常用方法
ret =re.findall('\d+', 'eva123egon4yuan567') print(ret)#返回满足条件的结果 ,放在一个列表里. ret2 = re.search('\d+',' ...
- Java-获取堆的大小
package com.tj; public class getHeapInfo { public static void main(String[] args) { //获取当前堆的大小 byte ...