在Linux中跟踪本地函数调用的工具 [英] Tool to trace local function calls in Linux

查看:105
本文介绍了在Linux中跟踪本地函数调用的工具的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找 ltrace strace ,可以跟踪可执行文件中的本地定义的函数。 ltrace只跟踪动态库调用和strace只跟踪系统调用。例如,给出以下C程序:

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 3 * x;
}

int main (void)
{
  printf("%d\n", triple(10));
  return 0;
}

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

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?

修改

几个说明:


  • 如果该工具还提供非本地功能的跟踪信息,那么这是可以的。

  • 我不想重新编译支持特定工具的程序,符号信息在可执行文件中应该是足够的。

  • 如果我可以使用该工具附加到现有进程,那么我会很好,我可以用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)

给定

#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)

这是我收集所有功能地址的方法:

Here is what i do to collect all function's addresses:

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之间输出了一些Current Language changed消息。但这很容易被淘汰。没有什么大不了的。

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.

这篇关于在Linux中跟踪本地函数调用的工具的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆