<html>
    <head>
      <base href="https://bugs.webkit.org/" />
    </head>
    <body>
      <p>
        <div>
            <b><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - run-webkit-tests should trigger a spindump when WebContent process is unresponsive"
   href="https://bugs.webkit.org/show_bug.cgi?id=159827#c18">Comment # 18</a>
              on <a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - run-webkit-tests should trigger a spindump when WebContent process is unresponsive"
   href="https://bugs.webkit.org/show_bug.cgi?id=159827">bug 159827</a>
              from <span class="vcard"><a class="email" href="mailto:dbates&#64;webkit.org" title="Daniel Bates &lt;dbates&#64;webkit.org&gt;"> <span class="fn">Daniel Bates</span></a>
</span></b>
        <pre>Comment on <span class=""><a href="attachment.cgi?id=284131&amp;action=diff" name="attach_284131" title="Patch">attachment 284131</a> <a href="attachment.cgi?id=284131&amp;action=edit" title="Patch">[details]</a></span>
Patch

View in context: <a href="https://bugs.webkit.org/attachment.cgi?id=284131&amp;action=review">https://bugs.webkit.org/attachment.cgi?id=284131&amp;action=review</a>

<span class="quote">&gt; Tools/ChangeLog:7
&gt; +</span >

Please explain the motivation for this change. From what I can tell the spindump(8) report is the concatenation of sample(1)ing all running processing plus some additional data. I take it that our interest in a spindump report is to capture the state of other WebKit processes (e.g. the Network process) when a WebContent process hangs to help diagnose a hard-to-reproduce test failure.

<span class="quote">&gt; Tools/Scripts/webkitpy/port/driver.py:192
&gt; +        if driver_input.test_name.startswith('http://') or driver_input.test_name.startswith('https://')  or driver_input.test_name.startswith('file:///'):
&gt; +            self._test_name = self.uri_to_test(driver_input.test_name)
&gt; +        else:
&gt; +            self._test_name = driver_input.test_name</span >

See my remark in _check_for_spindump_trigger() and in run_spindump() (defined in ios.py) that suggest making use of the existing machinery for sample reports. If we can make use of this machinery then we can remove this code.

<span class="quote">&gt; Tools/Scripts/webkitpy/port/driver.py:440
&gt; +        if not error_line.startswith(&quot;#TRIGGER SPINDUMP - &quot;):
&gt; +            return False
&gt; +
&gt; +        match = re.match('#TRIGGER SPINDUMP - (\S+)', error_line)
&gt; +        child_process_name = match.group(1) if match else 'WebProcess'
&gt; +        match = re.search('pid (\d+)', error_line)
&gt; +        child_process_pid = int(match.group(1)) if match else None
&gt; +        if child_process_pid:
&gt; +            self._port.run_spindump(self._test_name, child_process_pid)
&gt; +        self._server_process.write('#SPINDUMP FINISHED\n')
&gt; +        return True</span >

Is it necessary to have separate logic for spin dumps? I mean, this patch unconditionally replaces the machinery for sampling a process using sample(1) with machinery to call spindump(8). I do not see the need to only do one or the other, especially given that spindump(8) can only be run by root. Could we make use of the existing &quot;PROCESS UNRESPONSIVE&quot; message and incorporate the spin dump logic into Port.sample_process()? Could we incorporate the spin dump logic into Port.sample_process() such that we first call spindump(8) and if that command returns a non-zero exit status (say, the current user does not have password-less sudo access) then we call sample(1) on the WebContent process as we do today?

<span class="quote">&gt; Tools/Scripts/webkitpy/port/ios.py:432
&gt; +        parsed_filename = os.path.splitext(test_name)[0]
&gt; +        path_location = os.path.split(parsed_filename)[0]
&gt; +
&gt; +        if not os.path.exists(self.results_directory()):
&gt; +            os.makedirs(self.results_directory())
&gt; +        if not os.path.exists(self.results_directory() + '/' + path_location):
&gt; +            os.makedirs(self.results_directory() + '/' + path_location)</span >

Can we make use of the existing machinery (*) that copies sample(1) reports to the appropriate place in the results directory? If it makes sense to incorporate the spin dump logic into Port.sample_process() then we likely can pass Port.sample_file_path(..., ...) as the path for the -file argument to spindump(8) and make use of the existing machinery the collect samples and moves then to be near the test results for a failed test.

(*) After running a test Manager._look_for_new_crash_logs() is called to collect crash reports and sample reports. Manager._look_for_new_crash_logs() calls Port.look_for_new_samples() for the list of sample reports that were written and uses TestResultWriter.copy_sample_file() to copy each sample report to the appropriate place in the results directory.

<span class="quote">&gt; Tools/WebKitTestRunner/TestInvocation.cpp:212
&gt; +    char spindumpMessage[1024];
&gt; +#if PLATFORM(COCOA)
&gt; +    pid_t pid = WKPageGetProcessIdentifier(TestController::singleton().mainWebView()-&gt;page());
&gt; +    snprintf(spindumpMessage, 1024, &quot;#TRIGGER SPINDUMP - %s (pid %ld)\n&quot;, TestController::webProcessName(), static_cast&lt;long&gt;(pid));
&gt; +#else
&gt; +    snprintf(spindumpMessage, 1024, &quot;#TRIGGER SPINDUMP - %s\n&quot;, TestController::webProcessName());
&gt; +#endif</span >

It it necessary to emit a new message here &quot;TRIGGER SPINDUMP&quot;? Could we make use of the existing &quot;#PROCESS UNRESPONSIVE&quot; message and teach run-webkit-test to call spindump(8) when it sees this message instead of sample(1) on applicable platforms?

<span class="quote">&gt; Tools/WebKitTestRunner/TestInvocation.cpp:215
&gt; +    if (!TestController::singleton().usingServerMode())
&gt; +        return;</span >

Can you elaborate on this?

<span class="quote">&gt; Tools/WebKitTestRunner/TestInvocation.cpp:216
&gt; +    fputs(&quot;If running manually, hit enter...\n&quot;, stderr);</span >

Is this a workflow that most people will make use of? Running WebKitTestRunner in server mode and wanting to invoke spindump(8) by hand?

<span class="quote">&gt; Tools/WebKitTestRunner/TestInvocation.cpp:218
&gt; +    if (!fgets(spindumpMessage, 1024, stdin) || strcmp(spindumpMessage, &quot;#SPINDUMP FINISHED\n&quot;))</span >

Is it necessary to look for the message &quot;#SPINDUMP FINISHED\n&quot;? Would it be sufficient to use fgetc(3) to read a single newline character or EOF character and teach run-webkit-tests to emit a single newline character?

<span class="quote">&gt; Tools/WebKitTestRunner/TestInvocation.cpp:219
&gt; +        fputs(&quot;Spindump return failure\n&quot;, stderr);</span >

I take it that this output is helpful.</pre>
        </div>
      </p>
      <hr>
      <span>You are receiving this mail because:</span>
      
      <ul>
          <li>You are the assignee for the bug.</li>
      </ul>
    </body>
</html>