Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

win32 exit code after a crash guide

by bulk88 (Priest)
on Dec 29, 2014 at 03:25 UTC ( #1111601=perlmeditation: print w/replies, xml ) Need Help??

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
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
What on earth is 0x500? If you do the perl on Unix routine of 0x500 >> 8, you get 5. What is 5?

Referring to errno.h
#define EIO 5
C:\perl521\bin>perl -E"$! = 5; say $!" Input/output error
If I didn't tell you it is already is a crash, you would have thought the perl app did "exit($!);".

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.
C:\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>
0x96 = 0xC0000096 STATUS_PRIVILEGED_INSTRUCTION, valid machine op, but only allowed in kernel mode, not user mode

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 (Abbot) 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

    All right, very interesting, thank you.   Now, as a follow-on question:   is there anything out there (e.g. “elsewhere on CPAN”) that would enable people who are intending to write “portable” Perl routines ... and to write them but once ... to (“easily??”) circumvent these differences?   For example, if a Perl program that was originally written with Unix in mind, now needs to be moved to Windows, is there (for instance) some kind of translation-function that could massage a Windows return-code into what a Unix-eyed program would expect?   Something that would let the programmer elegantly ignore the differences, if they chose?

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlmeditation [id://1111601]
Approved by Athanasius
Front-paged by Arunbear
help
Chatterbox?
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others chanting in the Monastery: (3)
As of 2017-12-16 23:00 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    What programming language do you hate the most?




















    Results (459 votes). Check out past polls.

    Notices?