Exception handling 如何识别状态\u无效\u CRUNTIME\u参数异常

Exception handling 如何识别状态\u无效\u CRUNTIME\u参数异常,exception-handling,windbg,crash-dumps,secure-crt,Exception Handling,Windbg,Crash Dumps,Secure Crt,平台是Windows7SP1 我最近花了一些时间调试一个问题,该问题是由于一个代码向一个“安全”CRT函数传递了一个无效参数而引起的。结果,我的应用程序立即中止,没有任何警告或任何东西——甚至没有崩溃对话框 起初,我试图通过将Windbg连接到我的应用程序来解决这个问题。然而,当崩溃发生时,代码侵入Windbg时,几乎所有线程都已被杀死,只有一个线程Windbg必须侵入。关于到底出了什么问题,没有任何线索。因此,我将VisualStudio附加为调试器,当我的应用程序终止时,我看到每个线程都退出

平台是Windows7SP1

我最近花了一些时间调试一个问题,该问题是由于一个代码向一个“安全”CRT函数传递了一个无效参数而引起的。结果,我的应用程序立即中止,没有任何警告或任何东西——甚至没有崩溃对话框

起初,我试图通过将Windbg连接到我的应用程序来解决这个问题。然而,当崩溃发生时,代码侵入Windbg时,几乎所有线程都已被杀死,只有一个线程Windbg必须侵入。关于到底出了什么问题,没有任何线索。因此,我将VisualStudio附加为调试器,当我的应用程序终止时,我看到每个线程都退出,错误代码0xc0000417。这给了我一个线索,在某个地方有一个无效的参数问题

接下来,我尝试调试它的方法是再次将Windbg连接到我的应用程序,但这次随机(通过尝试和错误)在不同的位置放置断点,如
kernel32!TerminateThread
内核32!未处理的异常过滤器
内核32!SetUnhandledExceptionFilter

其中,在
SetUnhandledExceptionFilter
处放置一个断点,立即显示崩溃发生时出错线程的调用堆栈以及我们错误调用的CRT函数


问题:是否有任何直觉告诉我立即将bp置于SUEF上?我想更好地理解这一点,而不是通过反复试验来做到这一点。第二个问题是我通过VisualStudio确定的错误代码的w.r.t。在不使用VS的情况下,如何确定Windbg上的线程退出代码?

我只是想评论一下,但这个问题变得更大了,所以答案是肯定的

使用
windbg-I
将windbg设置为事后调试器也会将所有未处理的异常路由到windbg

Windbg-我应该将Windbg注册为后期调试程序
默认情况下,AeDebug注册表项中的Auto设置为1
如果不想调试每个程序,可以将其编辑为0
在wer对话框中为您提供额外的DoyouWantDebug选项

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;   
}
如果您选择调试

您可以查看调用堆栈

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
0:000>kPL
#ChildEBP-RetAddr
00 001ffdc8 77cf68d4 ntdll!KiFastSystemCallRet
01 001ffdcc 75e91fdb ntdll!NtTerminateProcess+0xc
02 001ffddc 012911d3内核库!终端进程+0x2c
03 001ffdec 01291174 ultos_沃森(
wchar_t*表达式=0x00000000“”,
wchar_t*函数名称=0x00000000“”,
wchar_t*文件名=0x00000000“”,
无符号整数行数=0,
无符号整数保留=0)+0x31
04 001ffe10 01291181 ultos_无效的\u参数(
wchar_t*表达式=,
wchar\u t*函数名称=,
wchar_t*文件名=,
无符号整数行数=,
无符号整数保留=)+0x7a
05 001ffe28 0128ad96 ultos_无效的参数\u noinfo(void)+0xc
06 001ffe3c 0128affa ultos!普通xtox(
无符号长原始值=0xffffffff,
字符*缓冲区=0x001ffea4“”,
无符号整数缓冲区计数=5,
无符号整数基数=0x10,
布尔值为负=假)+0x58
07 001ffe5c 0128b496 ultos!普通的(
无符号长值=0xFFFFFF,
字符*缓冲区=0x001ffea4“”,
无符号整数缓冲区计数=5,
无符号整数基数=0x10,
布尔值为负=假)+0x59
08 001ffe78 012712b2 ultos_ultoa_s(
无符号长值=0xFFFFFF,
字符*缓冲区=0x001ffea4“”,
无符号整数缓冲区计数=5,
整数基数=0n16)+0x18
09 001ffeac 0127151b ultos!主(空)+0x52
0a(内联)--ultos!调用_main+0x1d
0b 001ffef8 76403c45 ultos__scrt\u公共\u主要\u seh(无效)+0xff
0c 001fff04 77d137f5内核32!BaseThreadInitThunk+0xe
0d 001fff44 77d137c8 ntdll__RtlUserThreadStart+0x70
0e 001fff5c 00000000 ntdll_RtlUserThreadStart+0x1b

我会使用
procdump-ma-e1-n100
为进程中发生的每个未经处理的异常获取转储文件。我认为这不必要。
sxe*
有帮助吗?(或
sxe 0xc000417
如果您不想处理每个浮点溢出)相关:这将是一个很好的调试练习。你能把代码简化成a吗?@Thomas
sxe 0xc000417
是我尝试的第一件事,但没有成功。我想这不是一个真正的例外代码?顺便说一句,这不是一个浮点溢出(我想你在那里输入了一个错误。)至于一个简短/孤立的例子,如果你只是将nullptr传递给printf\s,你应该会看到同样的问题。谢谢!不幸的是,在这里发布之前,我已经尝试将Windbg作为后期调试工具。这没有帮助:-(您可以看到,我们正在编写在Excel.exe的进程空间中运行的加载项。即使我将Windbg设置为AeDebug ger,当崩溃发生时它确实会中断,但调用堆栈看起来完全是假的。我甚至尝试将procdump设置为AeDebug ger。无论它以这种方式产生什么转储都没有帮助。放置
bp
@
kernel32!SetUnhandledExceptionFilter
是唯一有效的东西。@Dilip:Excel可能有一个未处理的异常处理程序。也许您想询问SuperUser如何找出哪个加载项崩溃以及异常代码是什么。@Dilip如果它对您有效,我很高兴,但在SetUnhandledExceptionFilter上设置断点是件好事我的思维过程似乎无法消化主要原因,它所做的一切就是设置一个回调,以便在出现任何未处理的异常时调用,因此,如果它中断,则意味着某个异常(可能是excel或某个模块正在设置处理程序),因此这并不意味着异常
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