3

プラットフォームは Windows 7 SP1 です。

私は最近、コードが無効なパラメーターを「安全な」CRT 関数の 1 つに渡していたために発生した問題のデバッグに時間を費やしました。その結果、アプリケーションは警告も何ももなく、クラッシュ ダイアログさえも表示されずにすぐに中止されました。

最初に、Windbg を自分のアプリケーションにアタッチして、これを理解しようとしました。ただし、クラッシュが発生したとき、コードが Windbg に侵入するまでに、Windbg が侵入しなければならなかった 1 つのスレッドを除いて、ほぼすべてのスレッドが強制終了されていました。何が間違っていたのか、手がかりはありませんでした。そのため、代わりに Visual Studio をデバッガーとしてアタッチし、アプリケーションが終了したときに、すべてのスレッドがエラー コード0xc0000417で終了するのを見ました。それが、無効なパラメーターの問題がどこかにあるという手がかりを与えてくれました。

次に、これをデバッグしようとした方法は、もう一度 Windbg をアプリケーションにアタッチすることですが、今回はランダムに (試行錯誤により) 、 、 などのさまざまな場所にブレークポイントを配置kernel32!TerminateThreadkernel32!UnhandledExceptionFilterますkernel32!SetUnhandledExceptionFilter

多くの場合、ブレーク ポイントをSetUnhandledExceptionFilterすぐに配置すると、クラッシュが発生したときの問題のあるスレッドのコールスタックと、間違って呼び出していた CRT 関数が表示されました。

質問:すぐに bp をSUEFに配置するように指示された直感的なものはありますか? これをもう少しよく理解したいと思います。試行錯誤でこれを行うのではありません。2 番目の質問は、Visual Studio で特定したエラー コードに関するものです。VS に頼らずに、Windbg でスレッドの終了コードを特定するにはどうすればよいですか?

4

1 に答える 1

4

私はただコメントするつもりでしたが、これは大きくなったので答えです

windbg を使用して事後分析デバッガーとして設定するWindbg -I と、すべての未処理の例外が windbg にルーティングされます

Windbg -I should register windbg as postmortem debugger
by default by Auto is set to AeDebug Registry Key
if you want to debug all programs. これを 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 を使用して、このような 1 つのイベントを取得できます

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
于 2016-07-01T17:36:46.567 に答える