在LINUX中跟踪函数调用----http://stackoverflow.com/
http://stackoverflow.com/questions/311840/tool-to-trace-local-function-calls-in-linux I am looking for a tool like ltrace or strace that can trace locally defined functions in an executable.
ltrace only traces dynamic library calls and strace only traces system calls. For example, given the following C program: #include <stdio.h> int triple ( int x )
{
return * x;
} int main (void)
{
printf("%d\n", triple());
return ;
}
Running the program with ltrace will show the call to printf since that is a standard library function
(which is a dynamic library on my system) and strace will show all the system calls from the startup code,
the system calls used to implement printf, and the shutdown code, but I want something that will show me that the function triple was called.
Assuming that the local functions have not been inlined by an optimizing compiler and that the binary has not been stripped (symbols removed),
is there a tool that can do this? Edit A couple of clarifications: It is okay if the tool also provides trace information for non-local functions.
I don't want to have to recompile the program(s) with support for specific tools, the symbol information in the executable should be enough.
I would be really nice if I could use the tool to attach to existing processes like I can with ltrace/strace.
Assuming you only want to be notified for specific functions, you can do it like this: compile with debug informations (as you already have symbol informations, you probably also have enough debugs in) given #include <iostream> int fac(int n) {
if(n == )
return ;
return n * fac(n-);
} int main()
{
for(int i=;i<;i++)
std::cout << fac(i) << std::endl;
}
Use gdb to trace: [js@HOST2 cpp]$ g++ -g3 test.cpp
[js@HOST2 cpp]$ gdb ./a.out
(gdb) b fac
Breakpoint at 0x804866a: file test.cpp, line .
(gdb) commands
Type commands for when breakpoint is hit, one per line.
End with a line saying just "end".
>silent
>bt
>c
>end
(gdb) run
Starting program: /home/js/cpp/a.out
# fac (n=) at test.cpp: # fac (n=) at test.cpp:
# fac (n=) at test.cpp: # fac (n=) at test.cpp:
# fac (n=) at test.cpp:
# fac (n=) at test.cpp: # fac (n=) at test.cpp:
# fac (n=) at test.cpp:
# fac (n=) at test.cpp:
# fac (n=) at test.cpp: Program exited normally.
(gdb)
Here is what i do to collect all function's addresses: tmp=$(mktemp)
readelf -s ./a.out | gawk '
{
if($ == "FUNC" && $ != ) {
print "# code for " $NF;
print "b *0x" $;
print "commands";
print "silent";
print "bt 1";
print "c";
print "end";
print "";
}
}' > $tmp;
gdb --command=$tmp ./a.out;
rm -f $tmp Note that instead of just printing the current frame(bt 1
), you can do anything you like, printing the value of some global,
executing some shell command or mailing something if it hits thefatal_bomb_exploded
function :)
Sadly, gcc outputs some "Current Language changed" messages in between. But that's easily grepped out. No big deal.
System Tap can be used on a modern Linux box (Fedora , RHEL , etc.). First download the para-callgraph.stp script. Then run: $ sudo stap para-callgraph.stp 'process("/bin/ls").function("*")' -c /bin/ls
ls():->main argc=0x1 argv=0x7fff1ec3b038
ls(): ->human_options spec=0x0 opts=0x61a28c block_size=0x61a290
ls(): <-human_options return=0x0
ls(): ->clone_quoting_options o=0x0
ls(): ->xmemdup p=0x61a600 s=0x28
ls(): ->xmalloc n=0x28
ls(): <-xmalloc return=0x1efe540
ls(): <-xmemdup return=0x1efe540
ls(): <-clone_quoting_options return=0x1efe540
ls(): ->get_quoting_style o=0x1efe540
para-callgraph.stp #! /usr/bin/env stap function trace(entry_p, extra) {
%( $# > %? if (tid() in trace) %)
printf("%s%s%s %s\n",
thread_indent (entry_p),
(entry_p>?"->":"<-"),
ppfunc (),
extra)
} %( $# > %?
global trace
probe $.call {
trace[tid()] =
}
probe $.return {
delete trace[tid()]
}
%) probe $.call { trace(, $$parms) }
probe $.return { trace(-, $$return) }
Using Uprobes (since Linux 3.5)
Assuming you wanted to trace all functions in ~/Desktop/datalog-2.2/datalog
when calling it with the parameters -l ~/Desktop/datalog-2.2/add.lua ~/Desktop/datalog-2.2/test.dl
cd /usr/src/linux-`uname -r`/tools/perf
for i in `./perf probe -F -x ~/Desktop/datalog-2.2/datalog`;
do sudo ./perf probe -x ~/Desktop/datalog-2.2/datalog $i; done
sudo ./perf record -agR $(for j in $(sudo ./perf probe -l | cut -d' ' -f3); do echo "-e $j"; done)
~/Desktop/datalog-2.2/datalog -l ~/Desktop/datalog-2.2/add.lua ~/Desktop/datalog-2.2/test.dl
sudo ./perf report -G
Assuming you can re-compile (no source change required)
the code you want to trace with the gcc option -finstrument-functions, you can use etrace to get the function call graph. Here is what the output looks like: \-- main
| \-- Crumble_make_apple_crumble
| | \-- Crumble_buy_stuff
| | | \-- Crumble_buy
| | | \-- Crumble_buy
| | | \-- Crumble_buy
| | | \-- Crumble_buy
| | | \-- Crumble_buy
| | \-- Crumble_prepare_apples
| | | \-- Crumble_skin_and_dice
| | \-- Crumble_mix
| | \-- Crumble_finalize
| | | \-- Crumble_put
| | | \-- Crumble_put
| | \-- Crumble_cook
| | | \-- Crumble_put
| | | \-- Crumble_bake
On Solaris, truss (strace equivalent) has the ability to filter the library to be traced.
I'm was surprised when I discovered strace doesn't have such a capability.
在LINUX中跟踪函数调用----http://stackoverflow.com/的更多相关文章
- 在Linux中打印函数调用堆栈【原创】
本人学习笔记,代码参考如下网址 参考http://www.cnblogs.com/dma1982/archive/2012/02/08/2342215.html zhangbh@prolin-srv: ...
- 【Linux】Linux下跟踪记录每个用户对主机服务器进行的操作
linux中跟踪每个用户对主机的操作,看有人之前已经写过如此shell,可直接参考,参考如下: 1.记录操作信息 这个脚本需添加至/etc/profile 脚本如下: history USER_IP= ...
- Linux就这个范儿 第15章 七种武器 linux 同步IO: sync、fsync与fdatasync Linux中的内存大页面huge page/large page David Cutler Linux读写内存数据的三种方式
Linux就这个范儿 第15章 七种武器 linux 同步IO: sync.fsync与fdatasync Linux中的内存大页面huge page/large page David Cut ...
- linux 中的进程wait()和waitpid函数,僵尸进程详解,以及利用这两个函数解决进程同步问题
转载自:http://blog.sina.com.cn/s/blog_7776b9d3010144f9.html 在UNIX 系统中,一个进程结束了,但是他的父进程没有等待(调用wait / wait ...
- 用 set follow-fork-mode child即可。这是一个 gdb 命令,其目的是告诉 gdb 在目标应用调用fork之后接着调试子进程而不是父进程,因为在 Linux 中fork系统调用成功会返回两次,一次在父进程,一次在子进程
GDB的那些奇淫技巧 evilpan 收录于 Security 2020-09-13 约 5433 字 预计阅读 11 分钟 709 次阅读 gdb也用了好几年了,虽然称不上骨灰级玩家,但 ...
- Linux中find常见用法示例
·find path -option [ -print ] [ -exec -ok command ] {} \; find命令的参数: pathname: find命 ...
- 浅谈Linux中的信号处理机制(二)
首先谢谢 @小尧弟 这位朋友对我昨天夜里写的一篇<浅谈Linux中的信号处理机制(一)>的指正,之前的题目我用的“浅析”一词,给人一种要剖析内核的感觉.本人自知功力不够,尚且不能对着Lin ...
- 【日常小记】linux中强大且常用命令:find、grep【转】
转自:http://www.cnblogs.com/skynet/archive/2010/12/25/1916873.html 在linux下面工作,有些命令能够大大提高效率.本文就向大家介绍fin ...
- Linux中find常见用法
Linux中find常见用法示例 ·find path -option [ -print ] [ -exec -ok command ] {} \; find命令的参数 ...
随机推荐
- iOS: 属性列表介绍 Introduction to Property Lists
iOS: 属性列表介绍 Introduction to Property Lists 从本质上说, 属性列表就是苹果的对象数据序列化与反序列化方式 属性列表使用几种数据类型把数据组织为键值表和值表 P ...
- sizeof()用法
参考:sizeof_百度百科 sizeof()用法汇总(经典) 声明:本文是笔者抽出对自己有用的细节,对前两文的总结. 1.sizeof概念 sizeof是C语言中判断数据类型或者表达式长度符:不是一 ...
- ASP.NET 获取来源网站的网址,获取上一网页的网址,获取来源网页的URL,获取上一网页的URL
ASP.NET 获取来源网站的网址,获取上一网页的网址,获取来源网页的URL, 获取上一网页的URL Uri Url = HttpContext.Current.Request.UrlReferrer ...
- Python 计算已经过去多少个周末
def weekends_between(d1,d2): days_between = (d2-d1).days weekends, leftover = divmod(days_between,7) ...
- HTML Imports
为什么需要导入? 先想想你在 web 上是如何加载不同类型的资源.对于 JS,我们有 <script src>.<link rel="stylesheet"> ...
- Android中SharedPreferences和序列化结合保存对象数据
前言: 最近在做用户注册的时候,遇到了需要填写很多表单数据,不可能在一页把所有的数据都展示完全,因此采用了分页的方式,由于在用户填写数据数据之后我们需要对用户填写的数据进行暂时的记录的,当用户会到此页 ...
- Android开源项目发现--- 工具类Log篇(持续更新)
1.Catlog 手机端log查看工具,支持不同颜色显示.关键字过滤.级别过滤.进程id过滤.录制功能等 项目地址:https://github.com/nolanlawson/Catlog 在线演示 ...
- Supporting Multiple Screens 翻译 支持各种屏幕(上)
Supporting Multiple Screens 支持各种各样的屏幕尺寸.屏幕密度 Android runs on a variety of devices that offer differe ...
- C++ Prime:switch内部的变量定义
如果需要为某个case分支定义并初始化一个变量,我们应该把变量定义在块内,从而确保后面的所有case标签都在变量的作用域之外. case true: { // 正确,声明语句位于语句块内部 strin ...
- js对ajax返回数组的处理
引言: ajax异步传输,可以传输字符串,但是数组这样的数据,就不太好传递了,这个时候怎么办呢? 答案是可以通过json来处理,后台将数据数据进行json编码! 然后客户端,通过js来进行解析. 这样 ...