Skip to content

Commit fce1d10

Browse files
Julien GilliMylesBorins
Julien Gilli
authored andcommitted
test: add --abort-on-timeout option to test.py
Currently, when a process times out, it is terminated by sending it the SIGTERM signal. Sending SIGBART instead allows the operating system to generate a core file that can be investigated later using post-mortem debuggers such as llnode or mdb_v8. This can be very useful when investigating flaky tests that time out, since in that case the failure is difficult to reproduce, and being able to look at a core file makes a big difference. With these changes, passing the --abort-on-timeout command line option to tools/test.py now sends SIGABRT to processes timing out on all platforms but Windows. PR-URL: #11086 Ref: #11026 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Gibson Fahnestock <[email protected]> Reviewed-By: Sakthipriyan Vairamani <[email protected]> Reviewed-By: Santiago Gimeno <[email protected]> Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: Michael Dawson <[email protected]> Reviewed-By: Anna Henningsen <[email protected]>
1 parent 76e6e7e commit fce1d10

File tree

1 file changed

+22
-6
lines changed

1 file changed

+22
-6
lines changed

tools/test.py

+22-6
Original file line numberDiff line numberDiff line change
@@ -565,11 +565,11 @@ def HasFailed(self):
565565
return execution_failed
566566

567567

568-
def KillProcessWithID(pid):
568+
def KillProcessWithID(pid, signal_to_send=signal.SIGTERM):
569569
if utils.IsWindows():
570570
os.popen('taskkill /T /F /PID %d' % pid)
571571
else:
572-
os.kill(pid, signal.SIGTERM)
572+
os.kill(pid, signal_to_send)
573573

574574

575575
MAX_SLEEP_TIME = 0.1
@@ -588,6 +588,17 @@ def Win32SetErrorMode(mode):
588588
pass
589589
return prev_error_mode
590590

591+
592+
def KillTimedOutProcess(context, pid):
593+
signal_to_send = signal.SIGTERM
594+
if context.abort_on_timeout:
595+
# Using SIGABRT here allows the OS to generate a core dump that can be
596+
# looked at post-mortem, which helps for investigating failures that are
597+
# difficult to reproduce.
598+
signal_to_send = signal.SIGABRT
599+
KillProcessWithID(pid, signal_to_send)
600+
601+
591602
def RunProcess(context, timeout, args, **rest):
592603
if context.verbose: print "#", " ".join(args)
593604
popen_args = args
@@ -627,7 +638,7 @@ def RunProcess(context, timeout, args, **rest):
627638
while True:
628639
if time.time() >= end_time:
629640
# Kill the process and wait for it to exit.
630-
KillProcessWithID(process.pid)
641+
KillTimedOutProcess(context, process.pid)
631642
exit_code = process.wait()
632643
timed_out = True
633644
break
@@ -648,7 +659,7 @@ def RunProcess(context, timeout, args, **rest):
648659
while exit_code is None:
649660
if (not end_time is None) and (time.time() >= end_time):
650661
# Kill the process and wait for it to exit.
651-
KillProcessWithID(process.pid)
662+
KillTimedOutProcess(context, process.pid)
652663
exit_code = process.wait()
653664
timed_out = True
654665
else:
@@ -851,7 +862,7 @@ class Context(object):
851862

852863
def __init__(self, workspace, buildspace, verbose, vm, args, expect_fail,
853864
timeout, processor, suppress_dialogs,
854-
store_unexpected_output, repeat):
865+
store_unexpected_output, repeat, abort_on_timeout):
855866
self.workspace = workspace
856867
self.buildspace = buildspace
857868
self.verbose = verbose
@@ -863,6 +874,7 @@ def __init__(self, workspace, buildspace, verbose, vm, args, expect_fail,
863874
self.suppress_dialogs = suppress_dialogs
864875
self.store_unexpected_output = store_unexpected_output
865876
self.repeat = repeat
877+
self.abort_on_timeout = abort_on_timeout
866878

867879
def GetVm(self, arch, mode):
868880
if arch == 'none':
@@ -1385,6 +1397,9 @@ def BuildOptions():
13851397
result.add_option('--repeat',
13861398
help='Number of times to repeat given tests',
13871399
default=1, type="int")
1400+
result.add_option('--abort-on-timeout',
1401+
help='Send SIGABRT instead of SIGTERM to kill processes that time out',
1402+
default=False, dest="abort_on_timeout")
13881403
return result
13891404

13901405

@@ -1566,7 +1581,8 @@ def Main():
15661581
processor,
15671582
options.suppress_dialogs,
15681583
options.store_unexpected_output,
1569-
options.repeat)
1584+
options.repeat,
1585+
options.abort_on_timeout)
15701586

15711587
# Get status for tests
15721588
sections = [ ]

0 commit comments

Comments
 (0)