Index: tools/command_tester.py |
diff --git a/tools/command_tester.py b/tools/command_tester.py |
index aebd48ed96f66cf7d8ecd1a75b114bb42f4d3a3c..7c456283733b4328a7ec53fae57763bf2a4b093d 100755 |
--- a/tools/command_tester.py |
+++ b/tools/command_tester.py |
@@ -208,6 +208,10 @@ win64_exit_via_ntdll_patch = [ |
MungeWindowsErrorExit(STATUS_PRIVILEGED_INSTRUCTION)] |
+EXC_BAD_ACCESS = 1 |
+EXC_BAD_INSTRUCTION = 2 |
+ |
+ |
# 32-bit processes on Mac OS X return SIGBUS in most of the cases where Linux |
# returns SIGSEGV, except for actual x86 segmentation violations. 64-bit |
# processes on Mac OS X behave differently. |
@@ -243,6 +247,7 @@ status_map = { |
'linux2': [-11], # SIGSEGV |
'mac32': [-11], # SIGSEGV |
'mac64': [-11], # SIGSEGV |
+ 'mach_exception': EXC_BAD_ACCESS, |
'win32': win32_untrusted_crash_exit, |
'win64': win64_exit_via_ntdll_patch, |
}, |
@@ -264,6 +269,7 @@ status_map = { |
'linux2': [-11], # SIGSEGV |
'mac32': [-10], # SIGBUS |
'mac64': [-10], # SIGBUS |
+ 'mach_exception': EXC_BAD_ACCESS, |
'win32': win32_untrusted_crash_exit, |
'win64': win64_exit_via_ntdll_patch, |
}, |
@@ -271,6 +277,7 @@ status_map = { |
'linux2': [-11], # SIGSEGV |
'mac32': [-11], # SIGSEGV |
'mac64': [-10], # SIGBUS |
+ 'mach_exception': EXC_BAD_ACCESS, |
'win32': win32_untrusted_crash_exit, |
'win64': win64_exit_via_ntdll_patch, |
}, |
@@ -278,6 +285,7 @@ status_map = { |
'linux2': [-11], # SIGSEGV |
'mac32': [-10], # SIGBUS |
'mac64': [-11], # SIGSEGV |
+ 'mach_exception': EXC_BAD_ACCESS, |
'win32': [MungeWindowsErrorExit(STATUS_ACCESS_VIOLATION)], |
'win64': [MungeWindowsErrorExit(STATUS_ACCESS_VIOLATION)], |
}, |
@@ -285,6 +293,7 @@ status_map = { |
'linux2': [-11], # SIGSEGV |
'mac32': [-11], # SIGSEGV |
'mac64': [-11], # SIGSEGV |
+ 'mach_exception': EXC_BAD_ACCESS, |
'win32': [], |
'win64': [], |
}, |
@@ -302,6 +311,7 @@ status_map = { |
'linux2': [-11], # SIGSEGV |
'mac32': [-10], # SIGBUS |
'mac64': [-10], # SIGBUS |
+ 'mach_exception': 123, |
'win32': win32_untrusted_crash_exit, |
'win64': win64_exit_via_ntdll_patch, |
}, |
@@ -350,19 +360,15 @@ def ProcessOptions(argv): |
# thread, or additional output due to atexit functions, we scan the |
# output in reverse order for the signal signature. |
def GetNaClSignalInfoFromStderr(stderr): |
- sigNum = None |
- sigType = 'normal' |
- |
lines = stderr.splitlines() |
- |
# Scan for signal msg in reverse order |
for curline in reversed(lines): |
- words = curline.split() |
- if len(words) > 4 and words[0] == '**' and words[1] == 'Signal': |
- sigNum = int(words[2]) |
- sigType = words[4] |
- break |
- return sigNum, sigType |
+ match = re.match('\*\* (Signal|Mach exception) (\d+) from ' |
+ '(trusted|untrusted) code', curline) |
+ if match is not None: |
+ return match.group(0) |
+ return None |
+ |
def GetQemuSignalFromStderr(stderr, default): |
for line in reversed(stderr.splitlines()): |
@@ -412,6 +418,10 @@ def CheckExitStatus(failed, req_status, using_nacl_signal_handler, |
else: |
req_status = intended_statuses[0] |
+ if req_status == 'unwritable_exception_stack' and sys.platform != 'linux2': |
+ req_status = 'untrusted_segfault' |
+ |
+ expected_printed_status = None |
expected_sigtype = 'normal' |
if req_status in status_map: |
expected_statuses = status_map[req_status][GlobalPlatform] |
@@ -420,23 +430,26 @@ def CheckExitStatus(failed, req_status, using_nacl_signal_handler, |
expected_sigtype = 'trusted' |
elif req_status.startswith('untrusted_'): |
expected_sigtype = 'untrusted' |
+ |
else: |
expected_statuses = [int(req_status)] |
- # On 32-bit Windows, we cannot catch a signal that occurs in x86-32 |
- # untrusted code, so it always appears as a 'normal' exit, which |
- # means that the signal handler does not print a message. |
- if GlobalPlatform == 'win32' and expected_sigtype == 'untrusted': |
- expected_sigtype = 'normal' |
- |
- if expected_sigtype == 'normal': |
- expected_printed_signum = None |
- else: |
- assert sys.platform != 'win32' |
- assert len(expected_statuses) == 1 |
- assert expected_statuses[0] < 0 |
- expected_printed_signum = -expected_statuses[0] |
- expected_statuses = [IndirectSignal(expected_printed_signum)] |
+ if expected_sigtype != 'normal': |
+ if sys.platform == 'darwin': |
+ # Mac OS X |
+ expected_printed_status = '** Mach exception %d from %s code' % ( |
+ status_map[req_status]['mach_exception'], |
+ expected_sigtype) |
+ else: |
+ # Linux |
+ assert sys.platform != 'win32' |
+ assert len(expected_statuses) == 1 |
+ assert expected_statuses[0] < 0 |
+ expected_printed_signum = -expected_statuses[0] |
+ expected_printed_status = '** Signal %d from %s code' % ( |
+ expected_printed_signum, |
+ expected_sigtype) |
+ expected_statuses = [IndirectSignal(expected_printed_signum)] |
# If an uncaught signal occurs under QEMU (on ARM), the exit status |
# contains the signal number, mangled as per IndirectSignal(). We |
@@ -453,12 +466,11 @@ def CheckExitStatus(failed, req_status, using_nacl_signal_handler, |
Print(msg) |
failed = True |
if using_nacl_signal_handler and stderr is not None: |
- expected_printed = (expected_printed_signum, expected_sigtype) |
- actual_printed = GetNaClSignalInfoFromStderr(stderr) |
- msg = ('\nERROR: Command printed the signal info %s to stderr ' |
- 'but we expected %s' % |
- (actual_printed, expected_printed)) |
- if actual_printed != expected_printed: |
+ actual_printed_status = GetNaClSignalInfoFromStderr(stderr) |
+ msg = ('\nERROR: Command printed the signal info %r to stderr ' |
+ 'but we expected %r' % |
+ (actual_printed_status, expected_printed_status)) |
+ if actual_printed_status != expected_printed_status: |
Print(msg) |
failed = True |