自动将进入/退出功能日志添加到项目

Ben*_*ahi 25 c c++ compiler-construction debugging logging

我有第三方源代码,我必须调查.我想知道调用函数的顺序,但我不想浪费时间输入:

printf("Entered into %s", __FUNCTION__)
Run Code Online (Sandbox Code Playgroud)

printf("Exited from %s", __FUNCTION__)
Run Code Online (Sandbox Code Playgroud)

对于每个功能,我也不想触摸任何源文件.

你有什么建议吗?是否有一个编译器标志可以自动为我执行此操作?

澄清评论:

  • 我将交叉编译源代码以在ARM上运行它.
  • 我将用gcc编译它.
  • 我不想分析静态代码.我想跟踪运行时.所以doxygen不会让我的生活更轻松.
  • 我有源,我可以编译它.
  • 我不想使用面向方面编程.

编辑:我发现gdb提示符中的'frame'命令在那个时间点打印当前帧(或者,你可以说是函数名).也许,每次调用函数时,都可以(使用gdb脚本)调用'frame'命令.你怎么看?

Voi*_*oid 28

除了通常的调试器和面向方面的编程技术之外,您还可以使用gcc的-finstrument-functions命令行选项注入自己的检测功能.你必须实现自己的__cyg_profile_func_enter()__cyg_profile_func_exit()函数(extern "C"在C++中声明它们).

它们提供了一种跟踪从哪里调用函数的方法.但是,接口有点难以使用,因为例如,被调用的函数的地址及其调用站点被传递而不是函数名.您可以登录地址,然后使用类似的符号表拉相应的名称objdump --syms或者nm,假设当然符号尚未从有问题的二进制文件剥离.

它可能更容易使用gdb.因人而异.:)

  • gcc FTW再次=) (2认同)

Dan*_*Dan 11

你说"我也不想触摸任何源文件"......如果你让脚本为你做这个公平游戏?

在所有.cpp文件上运行此命令

sed 's/^{/{ENTRY/'
Run Code Online (Sandbox Code Playgroud)

因此它将它们转换为:

void foo()
{ENTRY
  // code here
}
Run Code Online (Sandbox Code Playgroud)

把它放在每个单元都可以#included的标题中:

#define ENTRY EntryRaiiObject obj ## __LINE__ (__FUNCTION__);

struct EntryRaiiObject {
  EntryRaiiObject(const char *f) : f_(f) { printf("Entered into %s", f_); }
  ~EntryRaiiObject() { printf("Exited from %s", f_); }
  const char *f_;
};
Run Code Online (Sandbox Code Playgroud)

您可能必须更好地使用sed脚本.您还可以将ENTRY宏放在您想要探测的任何其他位置,例如函数的一些深度嵌套的内部范围.

  • 你可以在一行开头用`{`开头有很多东西:结构等.你如何定位可靠的函数? (9认同)