Как узнать, скрыто ли другое исключение за точкой останова 80000003 (диалоговое окно WER)

Мое приложение, исполняемый файл, падает на удаленной машине. У меня нет доступа к этой машине, поэтому я запросил дамп, сгенерированный через диспетчер задач. Используя WinDbg, при выполнении команды!analyze -vЯ могу видеть следующий текст среди многих других

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

Как я могу узнать, несет ли он ответственность за аварию? Если это не так, как я могу определить истинную причину?

 Thomas Weller24 июн. 2016 г., 21:18
Этот вопрос тоже не идеален. «Что означает этот код исключения» уже получено в выводе WinDbg: это «Исключение инструкции прерывания». Удалите эту часть вопроса и обновите заголовок, например. «Как узнать, не скрыто ли другое исключение за точкой останова 80000003 диалога WER».
 Thomas Weller24 июн. 2016 г., 21:13
Это не дубликат. Дубликат не отвечает на вопрос, является ли точка останова действительной причиной или если другое исключение скрыто где-то за точкой останова. Дубликат - это на самом деле плохой вопрос с плохими ответами, потому что причина в том, что символы не были исправлены. Это вообще не связано с точкой останова.

Ответы на вопрос(1)

Является ли точка останова INT3 основной причиной?

TLDR: если!findstack kernel32!WerpReportFault дает результат, тогда это, вероятно, не первопричина.

Длинная версия:

Когда ваше приложение вылетает из-за необработанного исключения, ОС подхватит его с помощью функции Windows Error Reporting. Это приводит к нескольким техническим вещам:

диспетчер исключений вntdll начинает новую темув новом потоке сработает точка остановадиспетчер исключений также вызывает обработчик необработанного исключенияесли приложение не обработало такой обработчик, оно перенаправит обработку в систему отчетов об ошибках Windows (вkernel32) который показывает диалог

Если вы сделаете аварийный дамп в это время, вы увидите следующее:

Исключение точки останова, как указано в вашем вопросе

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

Поток, в котором нет ничего, кроме точки останова

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

Стек вызовов со связанными действиями, упомянутыми ранее

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 команда, так как это может произойти в любом потоке.

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 бит) из-за способа создания стека. Это не очень хорошо работает на x64 (64 бит), так какkb Команда не надежна. На x64 аргументы передаются в регистры вместо стека, ноkb Команда работает только со стеком.

Тем не менее, указатель исключения передаетсяWerpReportFault() как второй аргумент. Вы можете использовать этот указатель исключения, чтобы создать новый дамп с этим исключением в качестве основного исключения, например:

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

Затем закройте исходный дамп, откройте новый дамп и проанализируйте его снова, например, со следующими 4 командами в качестве отправной точки:

.symfix
.reload
.exr -1
!analyze -v
 Thomas Weller27 июн. 2016 г., 07:12
@RahulSingh: до или после того, как вы сделали.dump /ma /xp ...?
 Rahul Singh25 июн. 2016 г., 18:55
Спасибо за объяснение. Что делать, если для команды .exr -1 я получаю этот ExceptionAddress: 0000000000000000 ExceptionCode: 80000003 (исключение инструкции разрыва) ExceptionFlags: 00000000 NumberParameters: 0 .. т.е. нет адреса исключения

Ваш ответ на вопрос