在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 the fatal_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/perffor i in `./perf probe -F -x ~/Desktop/datalog-2.2/datalog`;do sudo ./perf probe -x ~/Desktop/datalog-2.2/datalog $i; donesudo ./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.dlsudo ./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命令的参数 ...
随机推荐
- Maven工程的Web调试
1.添加Server,将Web工程和Tomcat关联起来: 1)Windows->Show views->Other-->Servers,将会在下方弹出Server的窗口,然后右键添 ...
- HTML+JS版本的俄罗斯方块
<!doctype html><html><head></head><body> <div id="box" st ...
- 使用OPCDAAuto.dll编写C# OPC采集程序
在一台新机器上运行使用OPC自动化接口编写的C#程序报错如下: 索 COM 类工厂中 CLSID 为 {28E68F9A-8D75-11D1-8DC3-3C302A000000} 的组件失败,原因是出 ...
- mysql 中创建存储过程
mysql中创建存储过程和存储函数虽相对其他的sql语言相对复杂,但却功能强大,存储过程和存储函数更像是一种sql语句中特定功能的一种封装,这种封装可以大大简化外围调用语句的复杂程度. 首先以表emp ...
- 把Blob 转化为字符串查询。
在Oracle里面,有时候我们对于clob或者是blob作为varhcar2来查询. Clob可以直接使用 to char函数来转换. Blob就需要用 UTL_RAW.CAST_TO_VARCHAR ...
- FTP原理和cent OS vsFTPd架设
1.ftp为明码传输 2.客户端和服务端采用两条链路来分别进行命令和数据的传输.数据传输的模式分为主动链接和被动链接. 3.客户端在需要数据的时候,会告知服务器端采取主动或者被动的方式来链接. 4.如 ...
- bzoj 1040: [ZJOI2008]骑士 環套樹DP
1040: [ZJOI2008]骑士 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1755 Solved: 690[Submit][Status] ...
- API通常的url语法
?后面带的是get方式传递的值,如果有多个值,用 & 号分割.另外正式项目一般不用get方式传递,容易被人sql注入,即所谓的入侵. 详细看这篇http://www.cnblogs.com/k ...
- Eclipse 项目有红感叹号、小红叉
红感叹号: 问题原因]:工程中classpath中指向的包路径错误 [解决办法]:右键项目名称 BuildPath ---> Configure Build Paht...中,然后上面有几个选项 ...
- Fragment 常见问题
1. 因为Fragment是在3.0提出的,为了兼容低版本,需要引入一个android-support-v4.jar 2. 需要实例化的activity必须 extends FragmentActiv ...