Changeset 204253 in webkit


Ignore:
Timestamp:
Aug 8, 2016 9:18:33 AM (8 years ago)
Author:
commit-queue@webkit.org
Message:

run-webkit-tests should trigger a spindump when WebContent process is unresponsive
https://bugs.webkit.org/show_bug.cgi?id=159827

Patch by Jonathan Bedard <Jonathan Bedard> on 2016-08-08
Reviewed by Daniel Bates.

This change was spurred by a process hang which occurred between tests and did
not produce a meaningful crashlog.

  • Scripts/webkitpy/port/driver.py:

(Driver._check_for_driver_crash_or_unresponsiveness): Notify test controller when finished through stdin.

  • Scripts/webkitpy/port/ios.py:

(IOSSimulatorPort):
(IOSSimulatorPort.sample_process): Attempt spindump, but use sample if spindump fails.

  • Scripts/webkitpy/port/mac.py:

(MacPort):
(MacPort.sample_process): Attempt spindump, but use sample if spindump fails.

  • Scripts/webkitpy/port/mac_unittest.py: Changed expected values to match spindump calls, added specific spindump test.
  • Scripts/webkitpy/port/driver_unittest.py: Added dummy write function.
  • WebKitTestRunner/TestController.h:

(WTR::TestController::usingServerMode): Added accessor for m_usingServerMode.

  • WebKitTestRunner/TestInvocation.cpp:

(WTR::TestInvocation::dumpWebProcessUnresponsiveness): Wait for stdin before continuing when in server mode.

Location:
trunk/Tools
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/Tools/ChangeLog

    r204245 r204253  
     12016-08-08  Jonathan Bedard  <jbedard@apple.com>
     2
     3        run-webkit-tests should trigger a spindump when WebContent process is unresponsive
     4        https://bugs.webkit.org/show_bug.cgi?id=159827
     5
     6        Reviewed by Daniel Bates.
     7
     8        This change was spurred by a process hang which occurred between tests and did
     9        not produce a meaningful crashlog.
     10
     11        * Scripts/webkitpy/port/driver.py:
     12        (Driver._check_for_driver_crash_or_unresponsiveness): Notify test controller when finished through stdin.
     13
     14         * Scripts/webkitpy/port/ios.py:
     15        (IOSSimulatorPort):
     16        (IOSSimulatorPort.sample_process): Attempt spindump, but use sample if spindump fails.
     17        * Scripts/webkitpy/port/mac.py:
     18        (MacPort):
     19        (MacPort.sample_process): Attempt spindump, but use sample if spindump fails.
     20
     21        * Scripts/webkitpy/port/mac_unittest.py: Changed expected values to match spindump calls, added specific spindump test.
     22        * Scripts/webkitpy/port/driver_unittest.py: Added dummy write function.
     23
     24        * WebKitTestRunner/TestController.h:
     25        (WTR::TestController::usingServerMode): Added accessor for m_usingServerMode.
     26        * WebKitTestRunner/TestInvocation.cpp:
     27        (WTR::TestInvocation::dumpWebProcessUnresponsiveness): Wait for stdin before continuing when in server mode.
     28
    1292016-08-07  Dan Bernstein  <mitz@apple.com>
    230
  • trunk/Tools/Scripts/webkitpy/port/driver.py

    r204168 r204253  
    445445                self._port.sample_process(child_process_name, child_process_pid)
    446446            self.error_from_test += error_line
     447            self._server_process.write('#SAMPLE FINISHED\n')
    447448            return True
    448449        return self.has_crashed()
  • trunk/Tools/Scripts/webkitpy/port/driver_unittest.py

    r204168 r204253  
    207207                pass
    208208
     209            def write(self, str):
     210                pass
     211
    209212        def assert_crash(driver, error_line, crashed, name, pid, unresponsive=False):
    210213            self.assertEqual(driver._check_for_driver_crash_or_unresponsiveness(error_line), crashed)
  • trunk/Tools/Scripts/webkitpy/port/ios.py

    r204105 r204253  
    409409
    410410    def sample_process(self, name, pid):
    411         try:
    412             hang_report = self.sample_file_path(name, pid)
    413             self._executive.run_command([
    414                 "/usr/bin/sample",
    415                 pid,
    416                 10,
    417                 10,
    418                 "-file",
    419                 hang_report,
    420             ])
    421         except ScriptError as e:
    422             _log.warning('Unable to sample process:' + str(e))
     411        hang_report = self.sample_file_path(name, pid)
     412        exit_status = self._executive.run_command([
     413            "/usr/bin/sudo",
     414            "-n",
     415            "/usr/sbin/spindump",
     416            pid,
     417            10,
     418            10,
     419            "-file",
     420            hang_report,
     421        ], return_exit_code=True)
     422        if exit_status:
     423            try:
     424                self._executive.run_command([
     425                    "/usr/bin/sample",
     426                    pid,
     427                    10,
     428                    10,
     429                    "-file",
     430                    hang_report,
     431                ])
     432            except ScriptError as e:
     433                _log.warning('Unable to sample process:' + str(e))
    423434
    424435    def _path_to_helper(self):
  • trunk/Tools/Scripts/webkitpy/port/mac.py

    r202219 r204253  
    291291
    292292    def sample_process(self, name, pid):
    293         try:
    294             hang_report = self.sample_file_path(name, pid)
    295             self._executive.run_command([
    296                 "/usr/bin/sample",
    297                 pid,
    298                 10,
    299                 10,
    300                 "-file",
    301                 hang_report,
    302             ])
    303         except ScriptError as e:
    304             _log.warning('Unable to sample process:' + str(e))
     293        hang_report = self.sample_file_path(name, pid)
     294        exit_status = self._executive.run_command([
     295            "/usr/bin/sudo",
     296            "-n",
     297            "/usr/sbin/spindump",
     298            pid,
     299            10,
     300            10,
     301            "-file",
     302            hang_report,
     303        ], return_exit_code=True)
     304        if exit_status:
     305            try:
     306                self._executive.run_command([
     307                    "/usr/bin/sample",
     308                    pid,
     309                    10,
     310                    10,
     311                    "-file",
     312                    hang_report,
     313                ])
     314            except ScriptError as e:
     315                _log.warning('Unable to sample process:' + str(e))
    305316
    306317    def _path_to_helper(self):
  • trunk/Tools/Scripts/webkitpy/port/mac_unittest.py

    r202219 r204253  
    204204        oc.restore_output()
    205205
    206     def test_sample_process(self):
     206    def test_spindump(self):
    207207
    208208        def logging_run_command(args):
    209209            print args
     210
     211        port = self.make_port()
     212        port._executive = MockExecutive2(run_command_fn=logging_run_command)
     213        expected_stdout = "['/usr/bin/sudo', '-n', '/usr/sbin/spindump', 42, 10, 10, '-file', '/mock-build/layout-test-results/test-42-sample.txt']\n"
     214        OutputCapture().assert_outputs(self, port.sample_process, args=['test', 42], expected_stdout=expected_stdout)
     215
     216    def test_sample_process(self):
     217
     218        def logging_run_command(args):
     219            if args[0] == '/usr/bin/sudo':
     220                return 1
     221            print args
     222            return 0
    210223
    211224        port = self.make_port()
     
    214227        OutputCapture().assert_outputs(self, port.sample_process, args=['test', 42], expected_stdout=expected_stdout)
    215228
    216     def test_sample_process_throws_exception(self):
    217 
     229    def test_sample_process_exception(self):
    218230        def throwing_run_command(args):
     231            if args[0] == '/usr/bin/sudo':
     232                return 1
    219233            raise ScriptError("MOCK script error")
    220234
  • trunk/Tools/WebKitTestRunner/TestController.h

    r203743 r204253  
    8282
    8383    bool shouldShowWebView() const { return m_shouldShowWebView; }
    84 
     84    bool usingServerMode() const { return m_usingServerMode; }
    8585    void configureViewForTest(const TestInvocation&);
    8686   
  • trunk/Tools/WebKitTestRunner/TestInvocation.cpp

    r203743 r204253  
    4242#include <climits>
    4343#include <cstdio>
     44#include <unistd.h>
    4445#include <wtf/StdLibExtras.h>
    4546#include <wtf/text/CString.h>
     
    190191{
    191192    fprintf(stderr, "%s", errorMessage);
    192     char errorMessageToStderr[1024];
     193    char buffer[1024] = { };
    193194#if PLATFORM(COCOA)
    194195    pid_t pid = WKPageGetProcessIdentifier(TestController::singleton().mainWebView()->page());
    195     sprintf(errorMessageToStderr, "#PROCESS UNRESPONSIVE - %s (pid %ld)\n", TestController::webProcessName(), static_cast<long>(pid));
     196    snprintf(buffer, sizeof(buffer), "#PROCESS UNRESPONSIVE - %s (pid %ld)\n", TestController::webProcessName(), static_cast<long>(pid));
    196197#else
    197     sprintf(errorMessageToStderr, "#PROCESS UNRESPONSIVE - %s\n", TestController::webProcessName());
     198    snprintf(buffer, sizeof(buffer), "#PROCESS UNRESPONSIVE - %s\n", TestController::webProcessName());
    198199#endif
    199200
    200     dump(errorMessage, errorMessageToStderr, true);
     201    dump(errorMessage, buffer, true);
     202   
     203    if (!TestController::singleton().usingServerMode())
     204        return;
     205   
     206    if (isatty(fileno(stdin)) || isatty(fileno(stderr)))
     207        fputs("Grab an image of the stack, then hit enter...\n", stderr);
     208   
     209    if (!fgets(buffer, sizeof(buffer), stdin) || strcmp(buffer, "#SAMPLE FINISHED\n"))
     210        fprintf(stderr, "Failed receive expected sample response, got:\n\t\"%s\"\nContinuing...\n", buffer);
    201211}
    202212
Note: See TracChangeset for help on using the changeset viewer.