【问题标题】:How do identify STATUS_INVALID_CRUNTIME_PARAMETER exception如何识别 STATUS_INVALID_CRUNTIME PARAMETER 异常
【发布时间】:2016-07-01 01:17:24
【问题描述】:

平台是 Windows 7 SP1。

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

起初,我试图通过将 Windbg 附加到我的应用程序来解决这个问题。然而,当崩溃发生时,当代码侵入 Windbg 时,几乎所有线程都已被杀死,除了一个 Windbg 必须侵入的线程。没有任何线索知道出了什么问题。因此,我将 Visual Studio 作为调试器附加,当我的应用程序终止时,我看到每个线程都以错误代码 0xc0000417 退出。 是什么让我知道某处存在无效参数问题。

接下来,我尝试调试的方法是再次将 Windbg 附加到我的应用程序,但这次随机(通过反复试验)在不同的地方放置断点,例如 kernel32!TerminateThreadkernel32!UnhandledExceptionFilterkernel32!SetUnhandledExceptionFilter .

其中,在SetUnhandledExceptionFilter 处设置断点会立即显示崩溃发生时违规线程的调用堆栈以及我们错误调用的 CRT 函数。

问题:有什么直观的东西应该告诉我立即将 bp 放在 SUEF 上?我想更好地理解这一点,而不是通过反复试验来做到这一点。第二个问题是我通过 Visual Studio 确定的错误代码。不求助于VS,如何确定Windbg上的线程退出码?

【问题讨论】:

  • 我会使用procdump -ma -e 1 -n 100 <processname> 为您的进程中发生的每个未处理异常获取转储文件。
  • 我认为没有必要这样做。 sxe * 有帮助吗? (或者sxe 0xc0000417,如果你不想处理每一个浮点溢出)
  • 这将是一个很好的调试练习。你能把代码减少到minimal reproducible example吗?
  • @Thomas sxe 0xc0000417 是我尝试的第一件事,但没有成功。我猜它不是真正的异常代码?顺便说一句,它不是浮点溢出(我想你在那里打错字了。)至于一个简短/孤立的例子,如果你只是将 nullptr 传递给 printf_s,你应该会看到同样的问题。

标签: exception-handling windbg crash-dumps secure-crt


【解决方案1】:

我本来只想评论,但这变得更大了,所以一个答案

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

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

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

【讨论】:

  • 谢谢!不幸的是,虽然我已经尝试将 Windbg 作为事后调试器,然后再发布到这里。这没有帮助:-(您看到我们正在编写在 Excel.exe 的进程空间中运行的加载项。即使我将 Windbg 设置为 AeDebug-ger,它在发生崩溃但调用时确实会中断堆栈看起来完全是假的。我什至尝试将 procdump 制作为 AeDebug-ger。无论以这种方式产生的任何转储都无济于事。放置 bp @ kernel32!SetUnhandledExceptionFilter 是唯一有效的方法。
  • @Dilip:Excel 可能有一个未处理的异常处理程序。也许您想向 SuperUser 询问如何找出哪些 AddIn 崩溃以及异常代码是什么。
  • @Dilip 如果它对你有用,那么我很高兴,但是在 SETUNHANDLEDEXCEPTIONFILTER 上设置断点是我的思维过程似乎无法消化的主要原因,它所做的只是设置一个回调以在任何情况下调用未处理的异常,所以如果它坏了,那么它意味着某个人(可能是 excel 或某些模块只是设置一个处理程序)所以这并不意味着发生了异常整个 suef 对我来说似乎是某种海市蜃楼
  • @blabb 我在这里发帖主要是因为我和你在同一条船上。我不太明白为什么要调用 SUEF。我将使用调用堆栈更新帖子,以便您自己查看。
猜你喜欢
  • 2012-08-16
  • 2017-10-19
  • 1970-01-01
  • 1970-01-01
  • 2016-02-02
  • 2011-06-25
  • 2019-07-27
  • 2020-11-16
  • 1970-01-01
相关资源
最近更新 更多