自动跟踪程序执行情况

发布于 2024-11-03 12:47:36 字数 1539 浏览 1 评论 0 原文

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

方觉久 2024-11-10 12:47:36

要跟踪函数进入/退出,您可以使用选项 -finstrument-functions 以便每次调用函数时,调用__cyg_profile_func_enter()函数,并在函数返回时调用__cyg_profile_func_exit()

您可以实现这些函数来跟踪被调用函数的地址,然后使用 nm 将地址转换为函数名称。

编辑etrace 完成这一切:它提供了源代码__cyg_profile_func_enter()__cyg_profile_func_exit() 以及将地址写入命名管道的函数以及用于读取地址并执行操作的 Perl 和 Python 脚本使用函数名称和缩进进行实际跟踪。

To trace the function entry/exit, you can recompile your code with the option -finstrument-functions so that each time a function is invoked, a __cyg_profile_func_enter() function is called, and __cyg_profile_func_exit() is called when the function returns.

You can implement those functions to trace the addresses on the called functions, and then use nm to convert the addresses into function names.

EDIT: etrace does all this: it provides the source code for the __cyg_profile_func_enter() and __cyg_profile_func_exit() and functions that write the addresses to a named pipe and a Perl and a Python script to read the addresses and do the actual tracing with the function names and indentation.

橘虞初梦 2024-11-10 12:47:36

对于 GCC,您可以使用分析支持进行构建,然后运行该程序。这将创建 gmon.out 文件,该文件又将包含程序执行的函数的(某种)跟踪。

不过,这甚至无法接近手写跟踪 printf() 的实用性或易用性。

For GCC, you could build with profiling support, and then run the program. That will create the gmon.out file, which in turn will contain a (sort of) trace of the functions executed by the program.

That will not even come close to the utility or ease of use of hand-written trace printf()s, though.

绾颜 2024-11-10 12:47:36

既然你问的是 gcc。它具有选项-finstrument-functions,允许您在调用函数之前和之后执行任意代码。

Since you were asking about gcc. It has the option -finstrument-functions that allows you to execute arbitrary code before and after calls to functions.

冷月断魂刀 2024-11-10 12:47:36

使用 Log4cxx

一旦您在配置文件中指定文件类型、文件名和文件大小,这将记录详细信息。

按照以下步骤运行示例程序。

USE Log4cxx.

This will log the details once you specify the file type,filename and file size in their configuration file.

Follow the steps to run the sample program.

葬﹪忆之殇 2024-11-10 12:47:36

我知道您不想为每个函数添加一些内容,但如果就像将 { 更改为 {_ 一样简单,这会赢得您的青睐吗?一些脚本可以自动完成此操作 - 如果您需要,请联系我。如果这确实有效,那么看看我放在一起的这个小实用程序 - 只需包含一个头文件,然后您就可以得到很好的便携式跟踪

https://github.com/goblinhack/callstack

例如:

void my_function (void)
{_
  // rest of code
}

随时调用 CALLSTACK_DUMP() 来转储当前的调用堆栈。

只要做

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

I know you don't want to add something to each function, but if it's as simple as changing { to {_ does that win you over? A bit of scripting can do this automatically - ping me if you need that. If this does work, then look at this small utility I put together - just a single header file to include and then you get nice portable tracing

https://github.com/goblinhack/callstack

e.g.:

void my_function (void)
{_
  // rest of code
}

Call CALLSTACK_DUMP() at any time to dump the current callstack.

Just do

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
简美 2024-11-10 12:47:36

如果您不想修改所有 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__ )

请注意,我在这里使用了一个很好的宏技巧:可变参数宏

If you don't want to modify all your printf() calls, I'd suggest doing something along those lines in a header file, and include it in all your C code files:

#ifndef DEBUG /* if not in debug mode, disable printf */
  #ifdef printf
    #undef printf
    #define printf(format, ...)
  #endif 
#endif

What's cool with that is that you can also replace printf with a logging function of your own:

#define printf(format, ...) my_log_function( format, ##__VA_ARGS__ )

Notice that I use here a nice macro trick: variadic macro.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文