summaryrefslogtreecommitdiff
path: root/win32
diff options
context:
space:
mode:
authorusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-05-02 02:34:11 +0000
committerusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-05-02 02:34:11 +0000
commit25acda257cdc336a83372acc21fb8b899bd25635 (patch)
treead49a227d1c13049460f155c016f43215e1a7950 /win32
parentfe2177fddc1d8f5d68b9deac5229f9e5130b52ec (diff)
* win32/win32.c (poll_child_status): [experimental] set the cause of
a child's death to status if its exitcode seems to be an error. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@40549 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'win32')
-rw-r--r--win32/win32.c34
1 files changed, 33 insertions, 1 deletions
diff --git a/win32/win32.c b/win32/win32.c
index cdac41b456..e6b736795c 100644
--- a/win32/win32.c
+++ b/win32/win32.c
@@ -3908,7 +3908,39 @@ poll_child_status(struct ChildRecord *child, int *stat_loc)
}
pid = child->pid;
CloseChildHandle(child);
- if (stat_loc) *stat_loc = exitcode << 8;
+ if (stat_loc) {
+ *stat_loc = exitcode << 8;
+ if (exitcode & 0xC0000000) {
+ static struct {
+ DWORD status;
+ int sig;
+ } table[] = {
+ {STATUS_ACCESS_VIOLATION, SIGSEGV},
+ {STATUS_ILLEGAL_INSTRUCTION, SIGILL},
+ {STATUS_PRIVILEGED_INSTRUCTION, SIGILL},
+ {STATUS_FLOAT_DENORMAL_OPERAND, SIGFPE},
+ {STATUS_FLOAT_DIVIDE_BY_ZERO, SIGFPE},
+ {STATUS_FLOAT_INEXACT_RESULT, SIGFPE},
+ {STATUS_FLOAT_INVALID_OPERATION, SIGFPE},
+ {STATUS_FLOAT_OVERFLOW, SIGFPE},
+ {STATUS_FLOAT_STACK_CHECK, SIGFPE},
+ {STATUS_FLOAT_UNDERFLOW, SIGFPE},
+ {STATUS_FLOAT_MULTIPLE_FAULTS, SIGFPE},
+ {STATUS_FLOAT_MULTIPLE_TRAPS, SIGFPE},
+ {0, 0}
+ };
+ int i;
+ for (i = 0; table[i].status; i++) {
+ if (table[i].status == exitcode) {
+ *stat_loc |= table[i].sig;
+ break;
+ }
+ }
+ // if unknown status, assume SEGV
+ if (!table[i].status)
+ *stat_loc |= SIGSEGV;
+ }
+ }
return pid;
}
return 0;