Как определить исключение STATUS_INVALID_CRUNTIME_PARAMETER
Платформа Windows 7 SP1.
Недавно я потратил некоторое время на отладку проблемы, которая была вызвана тем, что код передавал недопустимый параметр одной из "безопасных" функций CRT. В результате мое приложение было прервано сразу же без предупреждения или чего-либо еще - даже диалоговое окно сбоя.
Сначала я попытался выяснить это, подключив Windbg к моему приложению. Однако, когда произошел сбой, к тому времени, когда код ворвался в Windbg, почти все потоки были убиты, за исключением ОДНОГО потока, в который Windbg должен был проникнуть. Не было никакой подсказки относительно того, что было не так. Итак, я вместо этого подключил Visual Studio в качестве отладчика, и когда мое приложение завершилось, я увидел, что все потоки выходили с кодом ошибки 0xc0000417. Именно это дало мне понять, что где-то есть проблема с неверными параметрами.
Далее, я попытался отладить это, снова подключив Windbg к моему приложению, но на этот раз случайным образом (методом проб и ошибок) установил точки останова в разных местах, например kernel32!TerminateThread
, kernel32!UnhandledExceptionFilter
а также kernel32!SetUnhandledExceptionFilter
,
Из всего, что ставит точку останова на SetUnhandledExceptionFilter
сразу же показал вызов стека нарушающего потока, когда произошел сбой, и функцию CRT, которую мы неправильно вызывали.
Вопрос: Есть ли что-нибудь интуитивное, что могло бы сказать мне, чтобы я сразу же разместил bp на SUEF? Я хотел бы понять это немного лучше и не делать это методом проб и ошибок. Второй вопрос касается кода ошибки, который я определил с помощью Visual Studio. Не прибегая к VS, как я могу определить коды выхода потока на Windbg?
1 ответ
Я собирался просто прокомментировать, но это стало больше, так что ответ
установка windbg в качестве посмертного отладчика с помощью Windbg -I
также направит все необработанное исключение в windbg
Windbg - я должен зарегистрировать windbg как отладчик после смерти
по умолчанию Авто установлено на 1 в ключе реестра AeDebug
если вы не хотите отлаживать каждую программу, вы можете отредактировать это до 0
чтобы предоставить вам дополнительную опцию DoYouWanttoDebug в диалоге wer
reg query "hklm\software\microsoft\windows nt\currentversion\aedebug"
HKEY_LOCAL_MACHINE\software\microsoft\windows nt\currentversion\aedebug
Debugger REG_SZ "xxxxxxxxxx\windbg.exe" -p %ld -e %ld -g
Auto REG_SZ 0
при условии, что вы зарегистрировали посмертный отладчик и запустили этот код
#include <stdio.h>
#include <stdlib.h>
int main (void)
{
unsigned long input[] = {1,45,0xf001,0xffffffff};
int i = 0;
char buf[5] = {0};
for(i=0;i<_countof(input);i++)
{
_ultoa_s(input[i],buf,sizeof(buf),16);
printf("%s\n",buf);
}
return 1;
}
за исключением вы увидите диалог wer, как это
Теперь вы можете отладить эту программу
Windows также записывает код завершения необработанного исключения в журнал событий.
Вы можете использовать PowerShell для получения одного события, как это
PS C:\> Get-EventLog -LogName Application -Source "Application Error" -newest 1| format-list
Index : 577102
EntryType : Error
InstanceId : 1000
Message : Faulting application name:
ultos.exe, version: 0.0.0.0, time stamp: 0x577680f1
Faulting module name: ultos.exe, version:
0.0.0.0, time stamp: 0x577680f1
Exception code: 0xc0000417
Fault offset: 0x000211c2
Faulting process id: 0x4a8
Faulting application start time: 0x01d1d3aaf61c8aaa
Faulting application path: E:\test\ulto\ultos.exe
Faulting module path: E:\test\ulto\ultos.exe
Report Id: 348d86fc-3f9e-11e6-ade2-005056c00008
Category : Application Crashing Events
CategoryNumber : 100
ReplacementStrings : {ultos.exe, 0.0.0.0, 577680f1, ultos.exe...}
Source : Application Error
TimeGenerated : 7/1/2016 8:42:21 PM
TimeWritten : 7/1/2016 8:42:21 PM
UserName :
и если вы решите отлаживать
Вы можете просмотреть CallStack
0:000> kPL
# ChildEBP RetAddr
00 001ffdc8 77cf68d4 ntdll!KiFastSystemCallRet
01 001ffdcc 75e91fdb ntdll!NtTerminateProcess+0xc
02 001ffddc 012911d3 KERNELBASE!TerminateProcess+0x2c
03 001ffdec 01291174 ultos!_invoke_watson(
wchar_t * expression = 0x00000000 "",
wchar_t * function_name = 0x00000000 "",
wchar_t * file_name = 0x00000000 "",
unsigned int line_number = 0,
unsigned int reserved = 0)+0x31
04 001ffe10 01291181 ultos!_invalid_parameter(
wchar_t * expression = <Value unavailable error>,
wchar_t * function_name = <Value unavailable error>,
wchar_t * file_name = <Value unavailable error>,
unsigned int line_number = <Value unavailable error>,
unsigned int reserved = <Value unavailable error>)+0x7a
05 001ffe28 0128ad96 ultos!_invalid_parameter_noinfo(void)+0xc
06 001ffe3c 0128affa ultos!common_xtox<unsigned long,char>(
unsigned long original_value = 0xffffffff,
char * buffer = 0x001ffea4 "",
unsigned int buffer_count = 5,
unsigned int radix = 0x10,
bool is_negative = false)+0x58
07 001ffe5c 0128b496 ultos!common_xtox_s<unsigned long,char>(
unsigned long value = 0xffffffff,
char * buffer = 0x001ffea4 "",
unsigned int buffer_count = 5,
unsigned int radix = 0x10,
bool is_negative = false)+0x59
08 001ffe78 012712b2 ultos!_ultoa_s(
unsigned long value = 0xffffffff,
char * buffer = 0x001ffea4 "",
unsigned int buffer_count = 5,
int radix = 0n16)+0x18
09 001ffeac 0127151b ultos!main(void)+0x52
0a (Inline) -------- ultos!invoke_main+0x1d
0b 001ffef8 76403c45 ultos!__scrt_common_main_seh(void)+0xff
0c 001fff04 77d137f5 kernel32!BaseThreadInitThunk+0xe
0d 001fff44 77d137c8 ntdll!__RtlUserThreadStart+0x70
0e 001fff5c 00000000 ntdll!_RtlUserThreadStart+0x1b