<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#c25">Comment # 25</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=284354&amp;action=diff" name="attach_284354" title="Patch">attachment 284354</a> <a href="attachment.cgi?id=284354&amp;action=edit" title="Patch">[details]</a></span>
Patch

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

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

As implied by my remark in <a href="show_bug.cgi?id=159827#c18">comment #18</a>, please explain the motivation of this change in this ChangeLog.

<span class="quote">&gt; Tools/ChangeLog:19
&gt; +        * Scripts/webkitpy/port/driver.py:
&gt; +        (Driver._check_for_driver_crash_or_unresponsiveness): Notify test when finished through stdin
&gt; +        * Scripts/webkitpy/port/ios.py:
&gt; +        (IOSSimulatorPort):
&gt; +        (IOSSimulatorPort.sample_process): Default to spindump, attempt sample if fail
&gt; +        * Scripts/webkitpy/port/mac.py:
&gt; +        (MacPort):
&gt; +        (MacPort.sample_process): Default to spindump, attempt sample if fail
&gt; +        * WebKitTestRunner/TestController.h:
&gt; +        (WTR::TestController::usingServerMode): Added accessor
&gt; +        * WebKitTestRunner/TestInvocation.cpp:
&gt; +        (WTR::TestInvocation::dumpWebProcessUnresponsiveness): Wait for stdin before continuing</span >

Please use complete sentences that end in a period.

<span class="quote">&gt; Tools/Scripts/webkitpy/port/driver.py:447
&gt; +            self._server_process.write('#SAMPLE FINISHED\n')</span >

OK. Alternatively, we could have taught WebKitTestRunner to suspend itself (raise a SIGSTOP) when it detects an unresponsive process and then run-webkit-tests can send a SIGCONT when its done.

<span class="quote">&gt; Tools/Scripts/webkitpy/port/ios.py:435
&gt;          try:
&gt;              hang_report = self.sample_file_path(name, pid)
&gt; -            self._executive.run_command([
&gt; -                &quot;/usr/bin/sample&quot;,
&gt; +            exit_status = self._executive.run_command([
&gt; +                &quot;/usr/bin/sudo&quot;,
&gt; +                &quot;-n&quot;,
&gt; +                &quot;/usr/sbin/spindump&quot;,
&gt;                  pid,
&gt;                  10,
&gt;                  10,
&gt;                  &quot;-file&quot;,
&gt;                  hang_report,
&gt; -            ])
&gt; +            ], None, None, None, None, True, False)
&gt; +
&gt; +            if not exit_status == 0:
&gt; +                self._executive.run_command([
&gt; +                    &quot;/usr/bin/sample&quot;,
&gt; +                    pid,
&gt; +                    10,
&gt; +                    10,
&gt; +                    &quot;-file&quot;,
&gt; +                    hang_report,
&gt; +                ])
&gt;          except ScriptError as e:
&gt; -            _log.warning('Unable to sample process:' + str(e))
&gt; +            _log.warning('Unable to run spindump and sample process:' + str(e))</span >

I would write this as:

hang_report = self.sample_file_path(name, pid)
exit_code = self._executive.run_command(['/usr/bin/sudo', '-n', '/usr/sbin/spindump', pid, 10, 10, '-file', hang_report], return_exit_code=True)
if not exit_code:
    return
# User does not have password-less sudo access. Fall back to using sample(1).
try:
    self._executive.run_command([
        &quot;/usr/bin/sample&quot;,
        pid,
        10,
        10,
        &quot;-file&quot;,
        hang_report,
    ])
except ScriptError as e:
    _log.warning('Unable to sample process:' + str(e))

<span class="quote">&gt; Tools/Scripts/webkitpy/port/mac.py:316
&gt; -            self._executive.run_command([
&gt; -                &quot;/usr/bin/sample&quot;,
&gt; +            exit_status = self._executive.run_command([
&gt; +                &quot;/usr/bin/sudo&quot;,
&gt; +                &quot;-n&quot;,
&gt; +                &quot;/usr/sbin/spindump&quot;,
&gt;                  pid,
&gt;                  10,
&gt;                  10,
&gt;                  &quot;-file&quot;,
&gt;                  hang_report,
&gt; -            ])
&gt; +            ], None, None, None, None, True, False)
&gt; +
&gt; +            if not exit_status == 0:
&gt; +                self._executive.run_command([
&gt; +                    &quot;/usr/bin/sample&quot;,
&gt; +                    pid,
&gt; +                    10,
&gt; +                    10,
&gt; +                    &quot;-file&quot;,
&gt; +                    hang_report,
&gt; +                ])
&gt;          except ScriptError as e:
&gt; -            _log.warning('Unable to sample process:' + str(e))
&gt; +            _log.warning('Unable to run spindump and sample process:' + str(e))</span >

Ditto.

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

OK. Is it necessary to know whether we are running in server mode to know if we should prompt for input for sample completion before terminating the WebContent process? I suspect that waiting for a sample to be taken of an unresponsive WebContent process is mostly of interest to scripts such as run-webkit-tests (for the purpose of implementing it sample on timeout feature). Would it be sufficient to only prompt to sample the WebContent process if standard error is not attached to a tty (e.g.  isatty(fileno(stderr)) returns 0)?

<span class="quote">&gt; Tools/WebKitTestRunner/TestInvocation.cpp:206
&gt; +    if (isatty(fileno(stdin)))</span >

This does not seem correct. We should be checking whether standard error is a tty device as opposed to standard input because scripts that tend to capture standard output and standard error of a subprocess (like run-webkit-tests) tend to forward standard input to the subprocess.

<span class="quote">&gt; Tools/WebKitTestRunner/TestInvocation.cpp:209
&gt; +    fputs(&quot;Grab an image of the stack, then hit enter...\n&quot;, stderr);</span >

We should be checking if standard error is attached to a tty device before we emit this message just as we do above.

<span class="quote">&gt; Tools/WebKitTestRunner/TestInvocation.cpp:213
&gt; +#endif
&gt; +    
&gt; +    if (!fgets(buffer, sizeof(buffer), stdin) || strcmp(buffer, &quot;#SAMPLE FINISHED\n&quot;))
&gt; +        fputs(&quot;Failed to sample process\n&quot;, stderr);</span >

Maybe we could simplify the above logic to be:

...
dump(errorMessage, buffer, true);

if (!isatty(fileno(stderr))) {
    // Run-webkit-tests may have initiated a process sample of the unresponsive process. We wait for run-webkit-tests to
    // signal completion of its sample activity (it will signal regardless of whether it actually takes a process sample)
    // before we continue on and terminate the unresponsive process.
    if (!fgets(buffer, sizeof(buffer), stdin) || strcmp(buffer, &quot;#SAMPLE FINISHED\n&quot;))
        fprintf(stderr, &quot;Failed to receive expected sample finished response. Got \&quot;%s\&quot;. Continuing...&quot;, buffer);
}</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>