Modified: trunk/Tools/ChangeLog (222708 => 222709)
--- trunk/Tools/ChangeLog 2017-10-02 14:32:52 UTC (rev 222708)
+++ trunk/Tools/ChangeLog 2017-10-02 14:59:28 UTC (rev 222709)
@@ -1,3 +1,25 @@
+2017-10-02 Jonathan Bedard <[email protected]>
+
+ Log stack-trace for run-webkit-tests when interrupted
+ https://bugs.webkit.org/show_bug.cgi?id=176393
+ <rdar://problem/34262310>
+
+ Reviewed by Darin Adler.
+
+ When run-webkit-tests is stuck, it is difficult to immediately tell
+ why. Saving a stack-trace when run-webkit-tests is terminated
+ or stopped with CNTRL-C will make such issues easier to debug.
+
+ * Scripts/webkitpy/common/interupt_debugging.py: Added.
+ (log_stack_trace): Given a Python frame object, log a stack trace to
+ the provided file.
+ (log_stack_trace_on_term): Attach a listener to SIGTERM so that a
+ stack-trace can be logged when a program is terminated.
+ (log_stack_trace_on_cntrl_c): Attach a listener to SIGINT so that a
+ stack-trace can be logged when a program is CNTRL-Ced.
+ * Scripts/webkitpy/layout_tests/run_webkit_tests.py:
+ (main): Set handlers to log stack trace on interruption.
+
2017-10-02 Michael Catanzaro <[email protected]>
Remove ENABLE_CSS_REGIONS
Added: trunk/Tools/Scripts/webkitpy/common/interupt_debugging.py (0 => 222709)
--- trunk/Tools/Scripts/webkitpy/common/interupt_debugging.py (rev 0)
+++ trunk/Tools/Scripts/webkitpy/common/interupt_debugging.py 2017-10-02 14:59:28 UTC (rev 222709)
@@ -0,0 +1,75 @@
+# Copyright (C) 2017 Apple Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR
+# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import linecache
+import logging
+import signal
+import sys
+
+_log = logging.getLogger(__name__)
+
+
+def log_stack_trace(frame, file):
+ file.write('Traceback(most recent call last):\n')
+
+ def func(frame):
+ if not frame:
+ return
+ func(frame.f_back)
+ file.write(' File "{}", line {}, in {}\n'.format(frame.f_code.co_filename, frame.f_lineno, frame.f_code.co_name))
+ file.write(' {}\n'.format(linecache.getline(frame.f_code.co_filename, frame.f_lineno).lstrip().rstrip()))
+
+ func(frame)
+
+
+def log_stack_trace_on_term(output_file=None):
+ def handler(signum, frame):
+ file = open(output_file, 'w') if output_file else sys.stderr
+ if not file:
+ raise RuntimeError('{} cannot be opened'.format(output_file))
+
+ if file is sys.stderr:
+ file.write('\n')
+ else:
+ _log.critical('Stack trace saved to {}'.format(output_file))
+ file.write('SIGTERM signal received')
+ log_stack_trace(frame, file)
+ exit(-1)
+
+ signal.signal(signal.SIGTERM, handler)
+
+
+def log_stack_trace_on_cntrl_c(output_file=None):
+ def handler(signum, frame):
+ file = open(output_file, 'w') if output_file else sys.stderr
+ if not file:
+ raise RuntimeError('{} cannot be opened'.format(output_file))
+
+ if file is sys.stderr:
+ file.write('\n')
+ else:
+ _log.critical('Stack trace saved to {}'.format(output_file))
+ file.write('cntrl C received\n')
+ log_stack_trace(frame, file)
+ raise KeyboardInterrupt
+
+ signal.signal(signal.SIGINT, handler)
Modified: trunk/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests.py (222708 => 222709)
--- trunk/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests.py 2017-10-02 14:32:52 UTC (rev 222708)
+++ trunk/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests.py 2017-10-02 14:59:28 UTC (rev 222709)
@@ -35,6 +35,7 @@
import traceback
from webkitpy.common.host import Host
+from webkitpy.common.interupt_debugging import log_stack_trace_on_cntrl_c, log_stack_trace_on_term
from webkitpy.layout_tests.controllers.manager import Manager
from webkitpy.layout_tests.models.test_run_results import INTERRUPTED_EXIT_STATUS
from webkitpy.port import configuration_options, platform_options
@@ -73,6 +74,10 @@
print >> stderr, str(e)
return EXCEPTIONAL_EXIT_STATUS
+ stack_trace_path = host.filesystem.join(port.results_directory(), 'python_stack_trace.txt')
+ log_stack_trace_on_cntrl_c(output_file=stack_trace_path)
+ log_stack_trace_on_term(output_file=stack_trace_path)
+
if options.print_expectations:
return _print_expectations(port, options, args, stderr)