Title: [222709] trunk/Tools
Revision
222709
Author
[email protected]
Date
2017-10-02 07:59:28 -0700 (Mon, 02 Oct 2017)

Log Message

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.

Modified Paths

Added Paths

Diff

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)
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to