diff options
author | usa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2013-05-02 02:34:11 +0000 |
---|---|---|
committer | usa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2013-05-02 02:34:11 +0000 |
commit | 25acda257cdc336a83372acc21fb8b899bd25635 (patch) | |
tree | ad49a227d1c13049460f155c016f43215e1a7950 /win32 | |
parent | fe2177fddc1d8f5d68b9deac5229f9e5130b52ec (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.c | 34 |
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; |