Windows Perl doesn't have SIGSEGV or SIGILL or SIGBUS. This makes diagnosing a non-local crashed process very difficult. For example, on one of those CPANTesters boxes, you see
Referring to errno.h
The answer is, the bytes selected by the mask 0xFF00, after the child crashed, are truncated NTSTATUS codes AKA EXCEPTION_* codes. I wrote a test script which shows what all the common Win32 crashes look like.
0x1D = 0xC000001D STATUS_ILLEGAL_INSTRUCTION, this machine op doesn't exist on this CPU, you are probably trying to execute data pointer/garbage as a C function, without DEP
0x5 = 0xC0000005 STATUS_ACCESS_VIOLATION, SEGV, bad address
0x94 = 0xC0000094 STATUS_INTEGER_DIVIDE_BY_ZERO
0x3 = 0x80000003 STATUS_BREAKPOINT explicit software call to C debugger, notice this code starts with 0x8, not 0xC, 0xC0000003 is STATUS_INVALID_INFO_CLASS, which means bad parameter to a function call, and will never cause an exception/crash
Code used to generate above.
What on earth is 0x500? If you do the perl on Unix routine of 0x500 >> 8, you get 5. What is 5?t/middleware/connect.t ....... Dubious, test returned 5 (wstat 1280, 0x500) All 1 subtests passed Free to wrong pool 2e8aa90 not 6c4040 at C:/strawberry-perl-5.12.2.0/p +erl/site/lib/AnyEvent/HTTP.pm line 1083, <> line 6. t/middleware/loadbalancer.t .. Dubious, test returned 5 (wstat 1280, 0x500) No subtests run Free to wrong pool 2e145e0 not 34f90 at C:/strawberry-perl-5.12.2.0/pe +rl/site/lib/AnyEvent/HTTP.pm line 1083, <> line 6. t/middleware/rewrite.t ....... Dubious, test returned 5 (wstat 1280, 0x500) No subtests run
Referring to errno.h
#define EIO 5
If I didn't tell you it is already is a crash, you would have thought the perl app did "exit($!);".C:\perl521\bin>perl -E"$! = 5; say $!" Input/output error
The answer is, the bytes selected by the mask 0xFF00, after the child crashed, are truncated NTSTATUS codes AKA EXCEPTION_* codes. I wrote a test script which shows what all the common Win32 crashes look like.
0x96 = 0xC0000096 STATUS_PRIVILEGED_INSTRUCTION, valid machine op, but only allowed in kernel mode, not user modeC:\perl521\srcnewb4opt>perl -Ilib crashtest.pl disable_interrupts $? 9600 CHILD_ERROR_NATIVE 9600 illegal_instruction $? 1d00 CHILD_ERROR_NATIVE 1d00 deref_null $? 500 CHILD_ERROR_NATIVE 500 deref_neg1 $? 500 CHILD_ERROR_NATIVE 500 write_to_ro_mem $? 500 CHILD_ERROR_NATIVE 500 div_by_0 $? 9400 CHILD_ERROR_NATIVE 9400 call_c_debugger $? 300 CHILD_ERROR_NATIVE 300 C:\perl521\srcnewb4opt>
0x1D = 0xC000001D STATUS_ILLEGAL_INSTRUCTION, this machine op doesn't exist on this CPU, you are probably trying to execute data pointer/garbage as a C function, without DEP
0x5 = 0xC0000005 STATUS_ACCESS_VIOLATION, SEGV, bad address
0x94 = 0xC0000094 STATUS_INTEGER_DIVIDE_BY_ZERO
0x3 = 0x80000003 STATUS_BREAKPOINT explicit software call to C debugger, notice this code starts with 0x8, not 0xC, 0xC0000003 is STATUS_INVALID_INFO_CLASS, which means bad parameter to a function call, and will never cause an exception/crash
Code used to generate above.
From 67329fe8a4f5c4a606b9da4af955eed9e63b4698 Mon Sep 17 00:00:00 2001 From: Daniel Dragan <bulk88@hotmail.com> Date: Sun, 28 Dec 2014 22:21:47 -0500 Subject: [PATCH] add intentional crashing tests --- crashtest.pl | 12 ++++++++ ext/XS-APItest/APItest.xs | 66 ++++++++++++++++++++++++++++++++++++ ++++++++++ 2 files changed, 78 insertions(+), 0 deletions(-) create mode 100644 crashtest.pl diff --git a/crashtest.pl b/crashtest.pl new file mode 100644 index 0000000..98902d1 --- /dev/null +++ b/crashtest.pl @@ -0,0 +1,12 @@ +use Win32API::File; + +sub runtest { +my $fn = shift; +my $r = system(1, 'perl -Ilib -MXS::APItest -E"XS::APItest::'.$fn.'() +"'); +my $p = wait(); +printf($fn.' $? %x CHILD_ERROR_NATIVE %x'."\n", $?, ${^CHILD_ERROR_NA +TIVE}); +} + +Win32API::File::SetErrorMode(Win32API::File::SEM_NOGPFAULTERRORBOX()) +; +runtest($_) foreach(qw(disable_interrupts illegal_instruction deref_n +ull + deref_neg1 write_to_ro_mem div_by_0 call_c_debugg +er)); diff --git a/ext/XS-APItest/APItest.xs b/ext/XS-APItest/APItest.xs index 9f7ecf2..75ebe8e 100644 --- a/ext/XS-APItest/APItest.xs +++ b/ext/XS-APItest/APItest.xs @@ -4,6 +4,15 @@ #include "XSUB.h" #include "fakesdio.h" /* Causes us to use PerlIO below */ +#ifdef WIN32 +# include "dos.h" +# pragma intrinsic(_disable) +#pragma code_seg(push, ".text") +/* 0x0F 0x0B UD2 ins, 0xC3 retn ins, VC 64 doesnt support inline asm +*/ +__declspec(allocate(".text")) U8 ud2_ins[3] = { 0x0F, 0x0B, 0xC3 }; +#pragma code_seg() +#endif + typedef SV *SVREF; typedef PTR_TBL_t *XS__APItest__PtrTable; @@ -3819,6 +3828,63 @@ test_newOP_CUSTOM() OUTPUT: RETVAL +#ifdef WIN32 +void +disable_interrupts() +PPCODE: + /* disabling interrupts is illegal from user mode, causes EXCEPTI +ON_PRIV_INSTRUCTION */ + _disable(); + +void +illegal_instruction() +PREINIT: + void (*fud2)() = (void (*)()) ud2_ins; +PPCODE: + fud2(); + +void +call_c_debugger() +PPCODE: + DebugBreak(); + +#endif + +void +deref_null() +PREINIT: + int *nowhere = NULL; +PPCODE: + *nowhere = 0; + +void +deref_neg1() +PREINIT: + int *nowhere = (int*)(SSize_t)-1; +PPCODE: + *nowhere = 0; + +void +write_to_ro_mem() +PREINIT: + int *nowhere = (int*)PL_no_aelem; +PPCODE: + *nowhere = 0; + +UV +div_by_0(...) +PREINIT: + UV divisor; +CODE: + /* defeat CC optimizer */ + if(items >= 1) + divisor = SvUV(ST(0)); + else + divisor = 0; + RETVAL = 1 / divisor; +OUTPUT: + RETVAL + + MODULE = XS::APItest PACKAGE = XS::APItest::AUTOLOADtest int -- 1.7.9.msysgit.0
|
---|
Replies are listed 'Best First'. | |
---|---|
Re: win32 exit code after a crash guide
by salva (Canon) on Dec 29, 2014 at 09:48 UTC | |
Re: win32 exit code after a crash guide
by sundialsvc4 (Abbot) on Dec 29, 2014 at 12:51 UTC |
Back to
Meditations