记录/监控来自应用程序的所有函数调用

Posted

技术标签:

【中文标题】记录/监控来自应用程序的所有函数调用【英文标题】:Logging/monitoring all function calls from an application 【发布时间】:2008-09-30 07:36:25 【问题描述】:

我们正在开发的应用程序有问题。应用程序在启动时崩溃的情况很少见,例如千分之一。当崩溃发生时,它会关闭整个系统,计算机开始发出哔哔声并完全冻结,唯一的恢复方法是关闭电源(我们使用的是 Windows XP)。崩溃的罕见性加上我们无法闯入调试器甚至在它发生时生成堆栈转储的事实使得调试变得极其困难。

我正在寻找将所有函数调用记录到文件的东西。这样的工具存在吗?这应该不是不可能实现的,像 VTune 这样的分析器做的事情非常相似。

我们使用的是 Visual Studio 2008 (C++)。

谢谢

A.B.

【问题讨论】:

【参考方案1】:

记录函数入口/出口是解决问题的低级方法。我建议使用自动调试器检测(使用带有 regedit 的图像文件执行选项下的调试器键或使用我在下面提供链接的包中的 gflags)并尝试重现问题,直到它崩溃。此外,您可以使用脚本记录可疑模块的调试器函数调用历史记录或收集任何其他信息。 但是不知道您的应用程序的详细信息,很难提出解决方案。它是用户应用程序、服务还是驱动程序? “启动时崩溃”是什么意思 - 在 Windows 启动或应用程序启动时? 使用此debugger package 进行故障排除。

【讨论】:

【参考方案2】:

日志记录思想的唯一问题是,当系统崩溃时,最新的日志条目可能仍在缓存中,没有机会写入磁盘......

如果是我,我会尝试在另一台 PC 上运行该程序 - 可能是不稳定的硬件或驱动程序导致了问题。应用程序“不应该”能够关闭系统。

【讨论】:

【参考方案3】:

一些想法- 很有可能在您崩溃之前,应用程序中存在某种异常。如果您使用 SetUnhandledExceptionFilter() 为所有未处理的异常设置处理程序并将堆栈跟踪写入日志文件,则您可能有机会捕捉到正在运行的崩溃。 请记住在每次写入后刷新文件。

另一种选择是使用诸如strace 之类的工具,它将所有系统调用记录到内核中(有多种风格和实现,所以选择你最喜欢的)。如果您在崩溃前查看日志,您可能会找到罪魁祸首

【讨论】:

【参考方案4】:

您是否考虑过使用第二台机器作为远程调试器(通过网络)?当应用程序(和系统)崩溃时,第二台机器应该仍然显示一些有用的信息,如果不是问题的实际点的话。我相信 VC++ 至少在某些版本中具有这种能力。

【讨论】:

【参考方案5】:

对于 Visual C++,_penter() and _pexit() 可用于检测您的代码。

另见Method Call Interception in C++。

【讨论】:

【参考方案6】:

GCC(包括MingGW for Windows development 版本)有一个名为-finstrument-functions 的代码生成开关,它告诉编译器在每个函数调用周围发出对名为__cyg_profile_func_enter 和__cyg_profile_func_exit 的函数的特殊调用。对于 Visual C++,有类似的选项称为 /GH 和 /Gh。这些会导致编译器在函数调用周围发出对 __penter 和 __pexit 的调用。

这些检测模式可用于实现日志系统,您可以实现编译器生成的调用以输出到本地文件系统或网络上的另一台计算机。

如果可能,我也会尝试使用valgrind 或类似的检查工具来运行您的系统。这可能会在您的问题失控之前发现它。

【讨论】:

以上是关于记录/监控来自应用程序的所有函数调用的主要内容,如果未能解决你的问题,请参考以下文章

使用报表事件处理程序运行函数

使用 Grafana 监控来自 tomcat 的 http 错误

记录/重放 Java 方法调用的工具

使用vb 监控电脑活动记录

使用 Restkit 监控网络调用 IOS

C++:Linux上的pthread状态监控