如何知道80000003断点后是否隐藏了其他异常(WER对话框) [英] How to know if a different exception is hidden behind a 80000003 breakpoint (WER dialog)

查看:386
本文介绍了如何知道80000003断点后是否隐藏了其他异常(WER对话框)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的应用程序(可执行文件)在远程计算机上崩溃.我无权访问该计算机,因此我请求了通过任务管理器生成的转储.使用WinDbg,在执行命令!analyze -v时,我可以看到以下文本

My application, an executable, is crashing on a remote machine. I don't have access to that machine, so I requested a dump, generated through Task Manager. Using WinDbg, on executing the command !analyze -v, I can see the following text among many others

EXCEPTION_RECORD:  (.exr -1)
ExceptionAddress: 0000000000000000
ExceptionCode: 80000003 (Break instruction exception)
ExceptionFlags: 00000000
NumberParameters: 0

我怎么知道它是否是导致崩溃的原因?如果不是,该如何确定真正原因?

How can I know if it is responsible for the crash? If it is not, how do I identify the real cause?

推荐答案

INT3断点是否是根本原因?

TLDR:如果!findstack kernel32!WerpReportFault产生结果,则可能不是根本原因.

Is the INT3 breakpoint the root cause?

TLDR: if !findstack kernel32!WerpReportFault yields a result, then it's probably not the root cause.

长版:

当您的应用程序由于未处理的异常而崩溃时,操作系统将使用称为Windows错误报告的功能对其进行处理.这导致了一些技术问题:

When your application crashes due to an unhandled exception, the OS will pick it up with a feature called Windows Error Reporting. This results in a few technical things:

  1. ntdll中的异常分派器启动了一个新线程.
  2. 在新线程中,将触发一个断点
  3. 异常分派器还调用未处理的异常处理程序
  4. 如果您的应用程序没有此类处理程序,它将把处理转发到显示对话框的Windows错误报告(在kernel32中)
  1. the exception dispatcher in ntdll starts a new thread.
  2. in the new thread, a breakpoint is triggered
  3. the exception dispatcher also calls the unhandled exception handler
  4. if there's no such handler by your application, it will forward the handling to the Windows Error Reporting (in kernel32) which shows the dialog

如果您此时进行故障转储,则会看到以下内容:

If you take a crash dump at that time, you'll see the following:

  1. 问题中提到的断点异常

  1. A breakpoint exception as mentioned in your question

0:002> .exr -1
ExceptionAddress: 775f000c (ntdll!DbgBreakPoint)
   ExceptionCode: 80000003 (Break instruction exception)
  ExceptionFlags: 00000000
NumberParameters: 1
   Parameter[0]: 00000000

  • 一个只有断点的线程

  • A thread that has nothing inside but a breakpoint

    0:002> k
    ChildEBP RetAddr  
    02e2ff58 7767f926 ntdll!DbgBreakPoint
    02e2ff88 75b3338a ntdll!DbgUiRemoteBreakin+0x3c
    02e2ff94 77619f72 kernel32!BaseThreadInitThunk+0xe
    02e2ffd4 77619f45 ntdll!__RtlUserThreadStart+0x70
    02e2ffec 00000000 ntdll!_RtlUserThreadStart+0x1b
    

  • 具有前面提到的相关操作的调用堆栈

  • A call stack with the related actions mentioned before

    0:001> k
    ChildEBP RetAddr  
    01aff904 770715f7 ntdll!NtWaitForMultipleObjects+0x15
    01aff9a0 75b319f8 KERNELBASE!WaitForMultipleObjectsEx+0x100
    01aff9e8 75b34200    kernel32!WaitForMultipleObjectsExImplementation+0xe0
    01affa04 75b580a4 kernel32!WaitForMultipleObjects+0x18
    01affa70 75b57f63 kernel32!WerpReportFaultInternal+0x186
    01affa84 75b57858 kernel32!WerpReportFault+0x70
    01affa94 75b577d7 kernel32!BasepReportFault+0x20
    01affb20 776574ff kernel32!UnhandledExceptionFilter+0x1af
    01affb28 776573dc ntdll!__RtlUserThreadStart+0x62
    01affb3c 77657281 ntdll!_EH4_CallFilterFunc+0x12
    01affb64 7763b499 ntdll!_except_handler4+0x8e
    01affb88 7763b46b ntdll!ExecuteHandler2+0x26
    01affbac 7763b40e ntdll!ExecuteHandler+0x24
    01affc38 775f0133 ntdll!RtlDispatchException+0x127
    01affc38 6f8c20ce ntdll!KiUserExceptionDispatcher+0xf
    

  • 要确定WER断点,可以检查这三个条件.对于后者,您可以使用!findstack命令,因为它可能在任何线程上发生.

    To identify a WER breakpoint, you can check for these three conditions. For the latter, you can use the !findstack command, since it may happen on any thread.

    0:001> !findstack kernel32!WerpReportFault
    Thread 001, 2 frame(s) match
            * 04 01affa70 75b57f63 kernel32!WerpReportFaultInternal+0x186
            * 05 01affa84 75b57858 kernel32!WerpReportFault+0x70
    

    我希望方法名称不变.

    由于堆栈的创建方式,它适用于x86(32位).由于kb命令不可靠,因此无法在x64(64位)上正常工作.在x64上,参数在寄存器而不是堆栈中传递,但kb命令仅在堆栈中起作用.

    This works for x86 (32 bit) due to the way how the stack is created. It does not work well on x64 (64 bit), since the kb command is not reliable. On x64, arguments get passed in registers instead of the stack but the kb command only works with the stack.

    也就是说,异常指针作为第二个参数传递给WerpReportFault().您可以使用该异常指针创建一个新的转储,并将该异常作为主要异常,如下所示:

    That said, the exception pointer is passed to WerpReportFault() as the second argument. You can use that exception pointer to create a new dump with that exception as the primary exception like this:

    .dump /ma /xp <exception pointer> c:\path\to\newdump.dmp
    

    接下来,关闭源转储,打开新的转储并再次分析它,例如以以下4个命令为起点:

    Next, close the source dump, open the new dump and analyze it again, e.g. with the following 4 commands as a starting point:

    .symfix
    .reload
    .exr -1
    !analyze -v
    

    这篇关于如何知道80000003断点后是否隐藏了其他异常(WER对话框)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆