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
-
Are you posting in the right place? Check out Where do I post X? to know for sure.
-
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
<u> <ul>
-
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).
-
Want more info? How to link
or How to display code and escape characters
are good places to start.