【问题标题】:Programmatically log caller of function in C++ [duplicate]以编程方式记录 C++ 中的函数调用者 [重复]
【发布时间】:2014-08-06 10:13:48
【问题描述】:

我有一个 Mutex 对象,它的锁定函数在某些条件/时间被神秘地调用了很多次(它通过内部每个线程计数器进行跟踪,并以固定频率报告发生的总数)。如果我可以在代码中添加一个检查,例如,在固定时间段内每 100 次左右调用,它会记录谁调用了它,以便更好地了解谁可能有错,那就太好了。我认为这应该可以通过一些堆栈跟踪来实现,但我不确定从哪里开始或参考什么。有没有简单的方法来解决这个问题?

【问题讨论】:

  • 你不能只在调试器中设置断点吗?
  • 我可以,但是当它已经在运行并且日志记录会减少干扰时停止这个应用程序很困难/不方便
  • 您不能将 gdb 附加到进程并检查堆栈上的函数吗?
  • 您可能会向锁定函数添加一个参数,并让每个调用站点传递其自己的识别参数,例如一个整数。

标签: c++ linux stack-trace


【解决方案1】:

这可能是我推荐宏的少数几次之一。

将被调用函数的名称更改为对原始函数的名称进行轻微修改,例如将Mutex::get 更改为Mutex::get_with_mapping,并添加一个额外的参数以获取位置信息的字符串常量。

编写一个宏以将旧函数名称包装在对新函数的调用中,将当前函数的预处理器标记放在宏中:

#define get() get_with_mapping(__func__)

把这个宏放在 Mutex 对象的头文件的底部,这样就不会和 Mutex 对象的定义混淆了。希望这个宏不会破坏包含它的源文件中不应包含的任何内容。

修改 get(现在是 get_with_mapping)函数以记录所有传递给它的位置。您还可以在签名中添加文件名和行号。

【讨论】:

  • 这实际上给了我这样的编译器错误:error: expected ',' or '...' before 'FUNCTION' in #define funcA() funcB(FUNCTION)(与 func 相同的错误) - 我错过了什么吗?
  • @PalaceChan 当前函数的预处理符号是“__func__”,两边各有两个下划线。你用过吗?
  • 是的——它应该可以工作,尽管当我说#define funcA() funcB(X) 时它一直说“'X' 之前的预期标识符。(X 是两个下划线、func 和两个下划线)。 - 我需要引用什么吗?我认为它正在用 mapping_get 替换 get 的签名并且它缺少标识符
  • 您使用的是什么编译器(和版本)?错误的确切文本是什么,包括行号?是定义处的错误还是替换位置(“调用”)。不要在包含成员something_get() 声明的类定义之前的标题顶部定义宏get()。在类定义之后,在标题的底部定义此宏。
  • 我会说在广泛使用的互斥锁类中定义一个get 宏是纯粹的疯狂。我至少会称它为get_mutex 以限制您通过与其他代码冲突实现的破坏。或者,甚至不要打扰宏。只需在每个呼叫站点手动输入Mutex::get(__func__)。当然,这并没有那么多带来不便,而且很明显会发生什么。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-12-31
  • 2023-02-26
  • 2018-05-03
  • 1970-01-01
  • 2013-08-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多