我想知道我们是否可以在任何C或C ++应用程序中启用跟踪。
例如,使用gcc选项或小工具,我将启用跟踪,并在控制台上打印跟踪或转储到文件。
由于有很多文件和函数/类,我不想手动开始添加跟踪打印。
如果此类工具不可用,则下一步选择使用脚本并尝试在跟踪打印时添加。
strace
没有多大用处,因为它主要提供系统调用。
答案 0 :(得分:11)
要跟踪函数入口/出口,可以使用选项-finstrument-functions
重新编译代码,这样每次调用函数时,都会调用__cyg_profile_func_enter()
函数,而__cyg_profile_func_exit()
是函数返回时调用。
您可以实现这些函数来跟踪被调用函数的地址,并使用nm将地址转换为函数名。
编辑:etrace完成所有这些:它提供了__cyg_profile_func_enter()
和__cyg_profile_func_exit()
的源代码以及将地址写入命名管道的函数一个Perl和一个Python脚本来读取地址并使用函数名称和缩进进行实际跟踪。
答案 1 :(得分:4)
对于GCC,您可以使用profiling支持构建,然后运行该程序。这将创建gmon.out
文件,该文件又包含程序执行的(某种)函数跟踪。
尽管如此,这甚至不会接近手写跟踪printf()的实用性或易用性。
答案 2 :(得分:3)
因为你问的是gcc。它具有选项-finstrument-functions
,允许您在调用函数之前和之后执行任意代码。
答案 3 :(得分:1)
答案 4 :(得分:0)
如果您不想修改所有printf()
次来电,我建议您在头文件中沿着这些行进行操作,并将其包含在所有C代码文件中:
#ifndef DEBUG /* if not in debug mode, disable printf */
#ifdef printf
#undef printf
#define printf(format, ...)
#endif
#endif
有什么好处的,你也可以用你自己的日志记录功能替换 printf:
#define printf(format, ...) my_log_function( format, ##__VA_ARGS__ )
请注意,我在这里使用了一个很好的宏技巧:variadic macro。
答案 5 :(得分:0)
答案 6 :(得分:0)
使用Lttng但如果你想跟踪二进制文件系统基于linux的工具可能会有所帮助,它需要源代码检测。如果您需要使用方面编译器
进行编码和预编译,也可以使用Aspect C++答案 7 :(得分:0)
我知道你不想为每个功能添加一些东西,但是如果它就像改变{to {_那会赢得你的那么简单吗?一些脚本可以自动执行此操作 - 如果您需要,请ping我。如果这确实有效,那么看看我放在一起的这个小实用程序 - 只需要包含一个头文件,然后就可以获得良好的可移植跟踪
https://github.com/goblinhack/callstack
例如为:
void my_function (void)
{_
// rest of code
}
随时调用CALLSTACK_DUMP()来转储当前的callstack。
只做
make
./callstack
Stack dump:
(stack) 1 main.cpp void foo3(int, int), line 7
(stack) 2 main.cpp void foo2(int), line 12
(stack) 3 main.cpp void foo1(), line 17
(stack) 4 main.cpp int main(int32_t, char **), line 22