Diff
Modified: trunk/Tools/ChangeLog (204252 => 204253)
--- trunk/Tools/ChangeLog 2016-08-08 06:05:47 UTC (rev 204252)
+++ trunk/Tools/ChangeLog 2016-08-08 16:18:33 UTC (rev 204253)
@@ -1,3 +1,31 @@
+2016-08-08 Jonathan Bedard <jbed...@apple.com>
+
+ run-webkit-tests should trigger a spindump when WebContent process is unresponsive
+ https://bugs.webkit.org/show_bug.cgi?id=159827
+
+ 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.
+
2016-08-07 Dan Bernstein <m...@apple.com>
[Cocoa] Reply block leaks if the remote object doesn’t call it
Modified: trunk/Tools/Scripts/webkitpy/port/driver.py (204252 => 204253)
--- trunk/Tools/Scripts/webkitpy/port/driver.py 2016-08-08 06:05:47 UTC (rev 204252)
+++ trunk/Tools/Scripts/webkitpy/port/driver.py 2016-08-08 16:18:33 UTC (rev 204253)
@@ -444,6 +444,7 @@
if child_process_pid:
self._port.sample_process(child_process_name, child_process_pid)
self.error_from_test += error_line
+ self._server_process.write('#SAMPLE FINISHED\n')
return True
return self.has_crashed()
Modified: trunk/Tools/Scripts/webkitpy/port/driver_unittest.py (204252 => 204253)
--- trunk/Tools/Scripts/webkitpy/port/driver_unittest.py 2016-08-08 06:05:47 UTC (rev 204252)
+++ trunk/Tools/Scripts/webkitpy/port/driver_unittest.py 2016-08-08 16:18:33 UTC (rev 204253)
@@ -206,6 +206,9 @@
def stop(self, timeout):
pass
+ def write(self, str):
+ pass
+
def assert_crash(driver, error_line, crashed, name, pid, unresponsive=False):
self.assertEqual(driver._check_for_driver_crash_or_unresponsiveness(error_line), crashed)
self.assertEqual(driver._crashed_process_name, name)
Modified: trunk/Tools/Scripts/webkitpy/port/ios.py (204252 => 204253)
--- trunk/Tools/Scripts/webkitpy/port/ios.py 2016-08-08 06:05:47 UTC (rev 204252)
+++ trunk/Tools/Scripts/webkitpy/port/ios.py 2016-08-08 16:18:33 UTC (rev 204253)
@@ -408,18 +408,29 @@
return sample_files
def sample_process(self, name, pid):
- try:
- hang_report = self.sample_file_path(name, pid)
- self._executive.run_command([
- "/usr/bin/sample",
- pid,
- 10,
- 10,
- "-file",
- hang_report,
- ])
- except ScriptError as e:
- _log.warning('Unable to sample process:' + str(e))
+ hang_report = self.sample_file_path(name, pid)
+ exit_status = self._executive.run_command([
+ "/usr/bin/sudo",
+ "-n",
+ "/usr/sbin/spindump",
+ pid,
+ 10,
+ 10,
+ "-file",
+ hang_report,
+ ], return_exit_code=True)
+ if exit_status:
+ try:
+ self._executive.run_command([
+ "/usr/bin/sample",
+ pid,
+ 10,
+ 10,
+ "-file",
+ hang_report,
+ ])
+ except ScriptError as e:
+ _log.warning('Unable to sample process:' + str(e))
def _path_to_helper(self):
binary_name = 'LayoutTestHelper'
Modified: trunk/Tools/Scripts/webkitpy/port/mac.py (204252 => 204253)
--- trunk/Tools/Scripts/webkitpy/port/mac.py 2016-08-08 06:05:47 UTC (rev 204252)
+++ trunk/Tools/Scripts/webkitpy/port/mac.py 2016-08-08 16:18:33 UTC (rev 204253)
@@ -290,18 +290,29 @@
return sample_files
def sample_process(self, name, pid):
- try:
- hang_report = self.sample_file_path(name, pid)
- self._executive.run_command([
- "/usr/bin/sample",
- pid,
- 10,
- 10,
- "-file",
- hang_report,
- ])
- except ScriptError as e:
- _log.warning('Unable to sample process:' + str(e))
+ hang_report = self.sample_file_path(name, pid)
+ exit_status = self._executive.run_command([
+ "/usr/bin/sudo",
+ "-n",
+ "/usr/sbin/spindump",
+ pid,
+ 10,
+ 10,
+ "-file",
+ hang_report,
+ ], return_exit_code=True)
+ if exit_status:
+ try:
+ self._executive.run_command([
+ "/usr/bin/sample",
+ pid,
+ 10,
+ 10,
+ "-file",
+ hang_report,
+ ])
+ except ScriptError as e:
+ _log.warning('Unable to sample process:' + str(e))
def _path_to_helper(self):
binary_name = 'LayoutTestHelper'
Modified: trunk/Tools/Scripts/webkitpy/port/mac_unittest.py (204252 => 204253)
--- trunk/Tools/Scripts/webkitpy/port/mac_unittest.py 2016-08-08 06:05:47 UTC (rev 204252)
+++ trunk/Tools/Scripts/webkitpy/port/mac_unittest.py 2016-08-08 16:18:33 UTC (rev 204253)
@@ -203,10 +203,23 @@
port.stop_helper()
oc.restore_output()
+ def test_spindump(self):
+
+ def logging_run_command(args):
+ print args
+
+ port = self.make_port()
+ port._executive = MockExecutive2(run_command_fn=logging_run_command)
+ expected_stdout = "['/usr/bin/sudo', '-n', '/usr/sbin/spindump', 42, 10, 10, '-file', '/mock-build/layout-test-results/test-42-sample.txt']\n"
+ OutputCapture().assert_outputs(self, port.sample_process, args=['test', 42], expected_stdout=expected_stdout)
+
def test_sample_process(self):
def logging_run_command(args):
+ if args[0] == '/usr/bin/sudo':
+ return 1
print args
+ return 0
port = self.make_port()
port._executive = MockExecutive2(run_command_fn=logging_run_command)
@@ -213,9 +226,10 @@
expected_stdout = "['/usr/bin/sample', 42, 10, 10, '-file', '/mock-build/layout-test-results/test-42-sample.txt']\n"
OutputCapture().assert_outputs(self, port.sample_process, args=['test', 42], expected_stdout=expected_stdout)
- def test_sample_process_throws_exception(self):
-
+ def test_sample_process_exception(self):
def throwing_run_command(args):
+ if args[0] == '/usr/bin/sudo':
+ return 1
raise ScriptError("MOCK script error")
port = self.make_port()
Modified: trunk/Tools/WebKitTestRunner/TestController.h (204252 => 204253)
--- trunk/Tools/WebKitTestRunner/TestController.h 2016-08-08 06:05:47 UTC (rev 204252)
+++ trunk/Tools/WebKitTestRunner/TestController.h 2016-08-08 16:18:33 UTC (rev 204253)
@@ -81,7 +81,7 @@
void notifyDone();
bool shouldShowWebView() const { return m_shouldShowWebView; }
-
+ bool usingServerMode() const { return m_usingServerMode; }
void configureViewForTest(const TestInvocation&);
bool beforeUnloadReturnValue() const { return m_beforeUnloadReturnValue; }
Modified: trunk/Tools/WebKitTestRunner/TestInvocation.cpp (204252 => 204253)
--- trunk/Tools/WebKitTestRunner/TestInvocation.cpp 2016-08-08 06:05:47 UTC (rev 204252)
+++ trunk/Tools/WebKitTestRunner/TestInvocation.cpp 2016-08-08 16:18:33 UTC (rev 204253)
@@ -41,6 +41,7 @@
#include <WebKit/WKWebsiteDataStoreRef.h>
#include <climits>
#include <cstdio>
+#include <unistd.h>
#include <wtf/StdLibExtras.h>
#include <wtf/text/CString.h>
@@ -189,15 +190,24 @@
void TestInvocation::dumpWebProcessUnresponsiveness(const char* errorMessage)
{
fprintf(stderr, "%s", errorMessage);
- char errorMessageToStderr[1024];
+ char buffer[1024] = { };
#if PLATFORM(COCOA)
pid_t pid = WKPageGetProcessIdentifier(TestController::singleton().mainWebView()->page());
- sprintf(errorMessageToStderr, "#PROCESS UNRESPONSIVE - %s (pid %ld)\n", TestController::webProcessName(), static_cast<long>(pid));
+ snprintf(buffer, sizeof(buffer), "#PROCESS UNRESPONSIVE - %s (pid %ld)\n", TestController::webProcessName(), static_cast<long>(pid));
#else
- sprintf(errorMessageToStderr, "#PROCESS UNRESPONSIVE - %s\n", TestController::webProcessName());
+ snprintf(buffer, sizeof(buffer), "#PROCESS UNRESPONSIVE - %s\n", TestController::webProcessName());
#endif
- dump(errorMessage, errorMessageToStderr, true);
+ dump(errorMessage, buffer, true);
+
+ if (!TestController::singleton().usingServerMode())
+ return;
+
+ if (isatty(fileno(stdin)) || isatty(fileno(stderr)))
+ fputs("Grab an image of the stack, then hit enter...\n", stderr);
+
+ if (!fgets(buffer, sizeof(buffer), stdin) || strcmp(buffer, "#SAMPLE FINISHED\n"))
+ fprintf(stderr, "Failed receive expected sample response, got:\n\t\"%s\"\nContinuing...\n", buffer);
}
void TestInvocation::dump(const char* textToStdout, const char* textToStderr, bool seenError)