我正在寻找像ltrace或strace这样的工具,它可以跟踪可执行文件中的本地定义函数.ltrace仅跟踪动态库调用,而strace仅跟踪系统调用.例如,给定以下C程序:
#include <stdio.h>
int triple ( int x )
{
return 3 * x;
}
int main (void)
{
printf("%d\n", triple(10));
return 0;
}
Run Code Online (Sandbox Code Playgroud)
运行程序ltrace将显示调用,printf因为这是一个标准库函数(我的系统上是一个动态库),strace并将显示启动代码,用于实现printf的系统调用和关闭代码的所有系统调用,但我想要一些能告诉我函数triple被调用的东西.假设优化编译器没有内联本地函数,并且二进制文件没有被剥离(符号被删除),是否有工具可以做到这一点?
编辑
几点澄清:
如何调用感兴趣的gdb打印函数,根据堆栈的深度缩进?
我希望能够说出(制作):
(gdb) trace Foo* Bar* printf
Run Code Online (Sandbox Code Playgroud)
并让gdb打印所有以Foo或Bar开头的函数,因为它们被调用.有点像gnu cflow,除了使用调试符号和仅实际调用的打印函数,而不是所有可能的调用流.
无法帮助的工具包括cachegrind,callgrind和oprofile,它们最常调用函数的结果.我需要保留的调用顺序.
通配符(或等效的)是必不可少的,因为有很多Foo和Bar函数.虽然我愿意完全记录所有功能.或者,也许告诉gdb记录特定库中的所有函数.
某些GDB向导必须有一个用于此常见作业的脚本!
在不修改源代码的情况下,当调用某个函数(例如下例中的func100)时,如何跟踪调用哪些函数以及使用哪些参数.我想输出如下:
enter func100(p1001=xxx,p1002=xxx)
enter func110(p1101=xxx,p1102=xxx)
exit func110(p1101=xxx,p1102=xxx)
enter func120(p1201=xxx,p1202=xxx,p1203=xxx)
enter func121(p1211=xxx)
exit func121(p1211=xxx)
exit func120(p1201=xxx,p1202=xxx,p1203=xxx)
exit func100(p1001=xxx,p1002=xxx)
Run Code Online (Sandbox Code Playgroud)
这可行吗?或者最少修改源代码的解决方案是什么?
(编辑:根据当前"技巧"下面的第一个答案似乎是使用Atom处理器.但我希望一些gdb专家可以回答,如果这是一个基本的限制,或者是否在路线图上增加了对其他处理器的支持?)
反向执行似乎在我的环境中工作:我可以反向继续,查看合理的记录日志,并在其中移动:
(gdb) start
...Temporary breakpoint 5 at 0x8048460: file bang.cpp, line 13.
Starting program: /home/thomasg/temp/./bang
Temporary breakpoint 5, main () at bang.cpp:13
13 f(1000);
(gdb) record
(gdb) continue
Continuing.
Breakpoint 3, f (d=900) at bang.cpp:5
5 if(d) {
(gdb) info record
Active record target: record-full
Record mode:
Lowest recorded instruction number is 1.
Highest recorded instruction number is 1005.
Log contains 1005 instructions.
Max logged instructions is 200000.
(gdb) reverse-continue
Continuing.
Breakpoint 3, f (d=901) at bang.cpp:5
5 if(d) …Run Code Online (Sandbox Code Playgroud) 目前使用VS2005在Windows上编码(但不介意知道是否有其他编译器和平台的选项.我最感兴趣的是OSX作为替代平台.)我有一个C(没有C++)程序,我想要做以下......
给定一个功能,比如......
int MyFunction(int myparam)
{
// Entry point.
...
// Exit point.
return 1;
}
Run Code Online (Sandbox Code Playgroud)
我想在入口点和出口点放一段代码.但是,我宁愿不必修改已经存在的100个函数.有没有办法定义编译器将为我的所有函数注入的函数入口和退出代码,而无需全部修改它们?
我发现或尝试过的大多数解决方案都需要我编辑每一个功能,这是很多工作.我认为其他人必须已经打过这样的东西并解决了它.在我怀疑的这个要求中,我不能独一无二.
我在玩GDB时首先注意到它rbreak .,然后做了一个最小的例子:
(gdb) file hello_world.out
Reading symbols from hello_world.out...done.
(gdb) b _init
Breakpoint 1 at 0x4003e0
(gdb) b _start
Breakpoint 2 at 0x400440
(gdb) run
Starting program: /home/ciro/bak/git/cpp/cheat/gdb/hello_world.out
Breakpoint 1, _init (argc=1, argv=0x7fffffffd698, envp=0x7fffffffd6a8) at ../csu/init-first.c:52
52 ../csu/init-first.c: No such file or directory.
(gdb) continue
Continuing.
Breakpoint 2, 0x0000000000400440 in _start ()
(gdb) continue
Continuing.
Breakpoint 1, 0x00000000004003e0 in _init ()
(gdb) info breakpoints
Num Type Disp Enb Address What
1 breakpoint keep y <MULTIPLE>
breakpoint already hit …Run Code Online (Sandbox Code Playgroud) 假设我在 A() 和 A() 调用 B()。我刚刚进入 A() 并且我希望程序运行到我进入 B() 为止。它不必是特定的函数 B()。我只希望我的程序在进入新函数时暂停。有没有办法做到这一点?