gpt4 book ai didi

linux - 在 Linux 中跟踪本地函数调用的工具

转载 作者:IT老高 更新时间:2023-10-28 12:32:11 27 4
gpt4 key购买 nike

我正在寻找像 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;
}

使用 ltrace 运行程序将显示对 printf 的调用,因为这是一个标准库函数(这是我系统上的动态库)和 strace 将显示来自启动代码的所有系统调用、用于实现 printf 的系统调用和关闭代码,但我想要一些可以显示函数 triple 被调用的东西。假设本地函数没有被优化编译器内联并且二进制文件没有被剥离(删除符号),有没有工具可以做到这一点?

编辑

一些澄清:

  • 如果该工具还提供非本地函数的跟踪信息,也可以。
  • 我不想重新编译支持特定工具的程序,可执行文件中的符号信息应该足够了。
  • 如果我可以像使用 ltrace/strace 一样使用该工具附加到现有进程,我会非常好。

最佳答案

假设您只想收到特定功能的通知,您可以这样做:

用调试信息编译(因为你已经有符号信息,你可能也有足够的调试)

给定

#include <iostream>

int fac(int n) {
if(n == 0)
return 1;
return n * fac(n-1);
}

int main()
{
for(int i=0;i<4;i++)
std::cout << fac(i) << std::endl;
}

使用 gdb 进行跟踪:

[js@HOST2 cpp]$ g++ -g3 test.cpp
[js@HOST2 cpp]$ gdb ./a.out
(gdb) b fac
Breakpoint 1 at 0x804866a: file test.cpp, line 4.
(gdb) commands 1
Type commands for when breakpoint 1 is hit, one per line.
End with a line saying just "end".
>silent
>bt 1
>c
>end
(gdb) run
Starting program: /home/js/cpp/a.out
#0 fac (n=0) at test.cpp:4
1
#0 fac (n=1) at test.cpp:4
#0 fac (n=0) at test.cpp:4
1
#0 fac (n=2) at test.cpp:4
#0 fac (n=1) at test.cpp:4
#0 fac (n=0) at test.cpp:4
2
#0 fac (n=3) at test.cpp:4
#0 fac (n=2) at test.cpp:4
#0 fac (n=1) at test.cpp:4
#0 fac (n=0) at test.cpp:4
6

Program exited normally.
(gdb)

这是我收集所有函数地址的方法:

tmp=$(mktemp)
readelf -s ./a.out | gawk '
{
if($4 == "FUNC" && $2 != 0) {
print "# code for " $NF;
print "b *0x" $2;
print "commands";
print "silent";
print "bt 1";
print "c";
print "end";
print "";
}
}' > $tmp;
gdb --command=$tmp ./a.out;
rm -f $tmp

注意,除了打印当前帧(bt 1),你可以做任何你喜欢的事情,打印一些全局的值,执行一些 shell 命令或者如果它命中 fatal_bomb_exploded function :) 遗憾的是,gcc 在两者之间输出了一些“当前语言已更改”消息。但这很容易被发现。没什么大不了的。

关于linux - 在 Linux 中跟踪本地函数调用的工具,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/311840/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com