如何找到仅显示在日志中的第一手异常?

时间:2017-10-24 11:33:01

标签: java c# exception access-violation

我在我们的产品中偶然发现了一些奇怪的行为 - 每隔一段时间(几分钟到几天的游侠),我们的日志(我们通常会将特定日志写入的简单.txt文件)显示此消息:

******************************************************
****** Warning - First Chance Exception Caught! ******
******************************************************
Process Name       : C:\OurApp.exe
Process ID         : 27396
Thread ID          : 21616
Debugger Time      : 11:45:34.073 24/10/2017
Exception Code     : 0xC0000005 - EXCEPTION_ACCESS_VIOLATION
Exception Desc     : The thread tried to read from or write to a virtual address for which it does not have the appropriate access.
Extended Desc      : The thread attempted to read inaccessible data.
Extended Desc 2    : Virtual address of inaccessible data 0xC
Exception Address  : 0x100517E2
Resolved Address   :    <no module>  (No symbol)  [0x100517E2]
Stack Trace        :

    <no module>  (No symbol)  [0x85C5A7D8]
    Frames below may be incorrect and/or missing (symbol not found)

******************************************************

除此之外,没有特别的行为是明显的 - 它首先被报告为崩溃,但显然它并没有崩溃,只是不时将其打印到日志中。它不是我们的日志之一,并且这个警告不在任何代码文件中(我扫描整个仓库,而不仅仅是特定项目)。无论日志级别如何,都会打印出来 我也无法在任何文档中找到此消息(我们的应用程序是用c#编写的,但可能有用C ++ / Java编写的导入模块),所以到目前为止我还不确定如何找到罪魁祸首,我该如何阻止这种情况发生。 我确定OurApp.exe生成的进程将此内容写入日志(使用procmon检查)。
任何想法如何能找到让它发生的原因以及如何阻止它将非常感激!

1 个答案:

答案 0 :(得分:0)

只要它只是第一次机会异常,并且没有相关的负面症状,它可能就好了。

这是SEH(Stuctured Exception Handling)&#34; First Chance Exception&#34;,这是Windows上的操作系统功能。

使用SEH,异常过滤器(通常是C或C ++代码)可以选择尝试从第一次机会恢复#34;异常而不展开堆栈。

只有当没有异常过滤器提供恢复时,异常才会最终得到&#34;抛出&#34;像C ++,Java或C#异常。

OS级别代码(或本机代码库)使用第一次机会0xC0000005异常作为初次使用时初始化代码或数据的方式是很正常的。例如,它们用于延迟加载DLL - 第一次调用函数时会得到第一次机会异常,异常过滤器会加载DLL,然后告诉操作系统重试。

心灵调试:

你可能在某处执行代码:

intptr LogException(LPEXCEPTION_POINTERS pep){
    // Log the exception
    return EXCEPTION_CONTINUE_SEARCH;
}

__try{
    // Some code
}
__except(LogException(GetExceptionInformation())){}

你可能会改善你的&#34; LogException&#34;从异常记录中提取更多信息。

您已经在检索某些扩展数据。

在您的特定情况下,错误地址似乎是0xC。这可能是一个标记值,但它看起来也很可疑,就像你通过空指针调用C ++对象一样。

更多地考虑,没有模块和符号的事实表明这是属于Java或C#的JIT编码。如果是这种情况,你应该使用数组或结构时可能传入或返回空指针,可能是在JNI或P / Invoke方法中(但它也可能是COM方法)。