在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命令的参数 ...
随机推荐
- ListView item 中TextView 如何获取长按事件
昨天晚上小伙伴突然来信, ListView item中嵌套的TextView 无法获取长按事件 从前从来没有仔细留意过, coding后发现...果然没什么动静 而且没有合适的API让我调用获取Tex ...
- Day21 Django之Form文件上传、原生Ajax和实现抽屉实例
一.Form文件上传 """ Django settings for prev_chouti project. Generated by 'django-admin st ...
- JAVA面试题相关基础知识
1.面向对象的特征有哪些方面 ①抽象: 抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面.抽象并不打算了解全部问题,而只是选择其中的一部分,暂时不用部分细节 ...
- 常见排序算法(JS版)
常见排序算法(JS版)包括: 内置排序,冒泡排序,选择排序,插入排序,希尔排序,快速排序(递归 & 堆栈),归并排序,堆排序,以及分析每种排序算法的执行时间. index.html <! ...
- [BZOJ 2049] [Sdoi2008] Cave 洞穴勘测 【LCT】
题目链接:BZOJ - 2049 题目分析 LCT的基本模型,包括 Link ,Cut 操作和判断两个点是否在同一棵树内. Link(x, y) : Make_Root(x); Splay(x); F ...
- Displaying 1-16 of 86 results for: deep learning
Displaying 1-16 of 86 results for: deep learning Deep Learning By Adam Gibson, Josh Patterson Publis ...
- gridview数据导出到word和excel以及excel的导入
using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.UI ...
- bzoj2337
这句话感觉都能成定理了:xor问题逐位考虑……这道题就是这样,然后和bzoj3143和相似但这道题多了自环,于是我们设f[i]表示当前位由i走到n的后为1的数学期望显然f[n]=0,可得f[i]=si ...
- Solr -- Solr Facet 1
一.Facet介绍 solr facet 是solr搜索的一大特色,facet不好翻译,有说是垂直搜索,有说是分片搜索,但都不是很好,还是懒得翻译了,就叫facet ,具体功能看下面的例子意会吧. 比 ...
- bootstrap真是个好东西
之前就知道有bootstrap这么个东东,但是因为本身不做web,也就没有仔细了解.这次一个项目合作方使用django和bootstrap做的,有机会接触了一些,感觉确实非常好! 今天下午利用一个下午 ...