From: sgjesse@chromium.org Date: Wed, 29 Oct 2008 09:52:31 +0000 (+0000) Subject: By default disable the general protection fault message box when X-Git-Tag: upstream/4.7.83~25087 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=d9285da2a8343096d2cf8e67add0994e55dc7fc1;p=platform%2Fupstream%2Fv8.git By default disable the general protection fault message box when running tests on Windows. This requires Added the option --win-error-box to enable general protection fault message box which can be convenient when debugging failing tests on Windows. Added crash detection when running tests on Windows. The output is not fully polished but crashed indications are printed for the different progess indicators. Changed the OS::Abort on Windows from generating a "crash" (int3) to calling abort(). This is to avoid tests which are known to fail with out of memory errors to be detected as crashed tests. Review URL: http://codereview.chromium.org/8676 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@633 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/platform-win32.cc b/src/platform-win32.cc index 803df77..055008e 100644 --- a/src/platform-win32.cc +++ b/src/platform-win32.cc @@ -781,9 +781,10 @@ void OS::Sleep(int milliseconds) { void OS::Abort() { - // Redirect to windows specific abort to ensure - // collaboration with sandboxing. - __debugbreak(); + // Make the MSVCRT do a silent abort. + _set_abort_behavior(0, _WRITE_ABORT_MSG); + _set_abort_behavior(0, _CALL_REPORTFAULT); + abort(); } diff --git a/tools/test.py b/tools/test.py index 30f0f34..92e35e0 100755 --- a/tools/test.py +++ b/tools/test.py @@ -63,6 +63,7 @@ class ProgressIndicator(object): self.remaining = len(cases) self.total = len(cases) self.failed = [ ] + self.crashed = 0 self.terminate = False self.lock = threading.Lock() @@ -124,6 +125,8 @@ class ProgressIndicator(object): self.lock.acquire() if output.UnexpectedOutput(): self.failed.append(output) + if output.HasCrashed(): + self.crashed += 1 else: self.succeeded += 1 self.remaining -= 1 @@ -159,6 +162,8 @@ class SimpleProgressIndicator(ProgressIndicator): print "--- stdout ---" print failed.output.stdout.strip() print "Command: %s" % EscapeCommand(failed.command) + if failed.HasCrashed(): + print "--- CRASHED ---" if len(self.failed) == 0: print "===" print "=== All tests succeeded" @@ -167,6 +172,8 @@ class SimpleProgressIndicator(ProgressIndicator): print print "===" print "=== %i tests failed" % len(self.failed) + if self.crashed > 0: + print "=== %i tests CRASHED" % self.crashed print "===" @@ -178,7 +185,10 @@ class VerboseProgressIndicator(SimpleProgressIndicator): def HasRun(self, output): if output.UnexpectedOutput(): - outcome = 'FAIL' + if output.HasCrashed(): + outcome = 'CRASH' + else: + outcome = 'FAIL' else: outcome = 'pass' print 'Done running %s: %s' % (output.test.GetLabel(), outcome) @@ -194,8 +204,12 @@ class DotsProgressIndicator(SimpleProgressIndicator): if (total > 1) and (total % 50 == 1): sys.stdout.write('\n') if output.UnexpectedOutput(): - sys.stdout.write('F') - sys.stdout.flush() + if output.HasCrashed(): + sys.stdout.write('C') + sys.stdout.flush() + else: + sys.stdout.write('F') + sys.stdout.flush() else: sys.stdout.write('.') sys.stdout.flush() @@ -229,6 +243,8 @@ class CompactProgressIndicator(ProgressIndicator): if len(stderr): print self.templates['stderr'] % stderr print "Command: %s" % EscapeCommand(output.command) + if output.HasCrashed(): + print "--- CRASHED ---" def Truncate(self, str, length): if length and (len(str) > (length - 3)): @@ -344,12 +360,20 @@ class TestOutput(object): self.output = output def UnexpectedOutput(self): - if self.HasFailed(): + if self.HasCrashed(): + outcome = CRASH + elif self.HasFailed(): outcome = FAIL else: outcome = PASS return not outcome in self.test.outcomes + def HasCrashed(self): + if platform.system() == 'Windows': + return 0x80000000 & self.output.exit_code and not (0x3FFFFF00 & self.output.exit_code) + else: + return False + def HasFailed(self): execution_failed = self.test.DidFail(self.output) if self.test.IsNegative(): @@ -369,17 +393,34 @@ MAX_SLEEP_TIME = 0.1 INITIAL_SLEEP_TIME = 0.0001 SLEEP_TIME_FACTOR = 1.25 +SEM_INVALID_VALUE = -1 +SEM_NOGPFAULTERRORBOX = 0x0002 # Microsoft Platform SDK WinBase.h +def Win32SetErrorMode(mode): + prev_error_mode = SEM_INVALID_VALUE + try: + import ctypes + prev_error_mode = ctypes.windll.kernel32.SetErrorMode(mode); + except ImportError: + pass + return prev_error_mode + def RunProcess(context, timeout, args, **rest): if context.verbose: print "#", " ".join(args) popen_args = args + prev_error_mode = SEM_INVALID_VALUE; if platform.system() == 'Windows': popen_args = '"' + subprocess.list2cmdline(args) + '"' + if context.supress_dialogs: + # Try to change the error mode to avoid dialogs on fatal errors. + Win32SetErrorMode(SEM_NOGPFAULTERRORBOX) process = subprocess.Popen( shell = (platform.system() == 'Windows'), args = popen_args, **rest ) + if platform.system() == 'Windows' and context.supress_dialogs and prev_error_mode != SEM_INVALID_VALUE: + Win32SetErrorMode(prev_error_mode) # Compute the end time - if the process crosses this limit we # consider it timed out. if timeout is None: end_time = None @@ -543,13 +584,14 @@ PREFIX = {'debug': '_g', 'release': ''} class Context(object): - def __init__(self, workspace, buildspace, verbose, vm, timeout, processor): + def __init__(self, workspace, buildspace, verbose, vm, timeout, processor, supress_dialogs): self.workspace = workspace self.buildspace = buildspace self.verbose = verbose self.vm_root = vm self.timeout = timeout self.processor = processor + self.supress_dialogs = supress_dialogs def GetVm(self, mode): name = self.vm_root + PREFIX[mode] @@ -1030,6 +1072,11 @@ def BuildOptions(): default=1, type="int") result.add_option("--time", help="Print timing information after running", default=False, action="store_true") + if platform.system() == 'Windows': + result.add_option("--supress-dialogs", help="Supress Windows dialogs for crashing tests", + dest="supress_dialogs", default=True, action="store_true") + result.add_option("--no-supress-dialogs", help="Display Windows dialogs for crashing tests", + dest="supress_dialogs", action="store_false") return result @@ -1159,7 +1206,8 @@ def Main(): context = Context(workspace, buildspace, VERBOSE, join(buildspace, 'shell'), options.timeout, - GetSpecialCommandProcessor(options.special_command)) + GetSpecialCommandProcessor(options.special_command), + options.supress_dialogs) if options.j != 1: options.scons_flags += ['-j', str(options.j)] if not options.no_build: