在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命令的参数 ...
随机推荐
- ng-html 报 不安全 警告解决办法
app.filter('to_trusted',['$sce',function($sce){ return function(text){ return $sce.trustAsHtml(text) ...
- 复制档案或目录 linux cp命令详解
cp (复制档案或目录) [root@linux ~]# cp [-adfilprsu] 来源档(source) 目的檔(destination)[root@linux ~]# cp [options ...
- adb的logcat使用
预备:安装刷机精灵,实用工具->adb命令行 1. 对于多机设备,首先使用adb devices来获知设备名称: 2. 将log输出到电脑:adb –s [设备名称] shell logcat ...
- BZOJ 2005 能量采集
Description 栋栋有一块长方形的地,他在地上种了一种能量植物,这种植物可以采集太阳光的能量.在这些植物采集能量后,栋栋再使用一个能量汇集机器把这些植物采集到的能量汇集到一起. 栋栋的植物种得 ...
- c语言exit和return区别,在fork和vfork中使用
转自c语言exit和return区别,在fork和vfork中使用 exit函数在头文件stdlib.h中. 简述: exit(0):正常运行程序并退出程序: exit(1):非正常运行导致退出程序: ...
- validationEngine[转]
随笔- 31 文章- 0 评论- 40 validationEngine中文版 — jquery强大的表单验证插件 中文汉化版,官方只有英文的.同时根据中国国情修改了部分验证规则. 这个插件 ...
- hibernate异常:Could not determine type for: java.util.Set
根本原因:我实体类中的类型是raw,没法直接实例化的类型.private List<String> rightChoices;private Set<String> multi ...
- Condition 的使用
Condition 将 Object 监视器方法(wait.notify 和 notifyAll)分解成截然不同的对象,以便通过将这些对象与任意 Lock 实现组合使用,为每个对象提供多个等待 set ...
- 移植qt5.3.1到arm
最近刚入手一款开发板(比较低端,刚毕业工作还没一个月,穷屌丝一个).在学校以前都是用的是Friendly Arm的6410,使用的qt版本是使用的最多的4.7.0版本,入手的板子是4.7.4.qt5出 ...
- VC++6.0 编写插件(图文并茂)
下午偶然注意到VC++6.0新建工程标签页下的DevStudio Add-in Wizard,没有接触过,看名字是给Developer Studio开发插件,心生喜感,于是百度之,发生百度检索几乎找不 ...