bisect-kit: output error messages to console if fatal
This change helps users finding issues easier.
BUG=b:130786578,b:127369305
TEST=run diagnose_cros_autotest.py manually
Change-Id: I3e252141078cb880c305bc0e1f202fd3ff27e0e3
Reviewed-on: https://chromium-review.googlesource.com/1627409
Commit-Ready: Kuang-che Wu <kcwu@chromium.org>
Tested-by: Kuang-che Wu <kcwu@chromium.org>
Legacy-Commit-Queue: Commit Bot <commit-bot@chromium.org>
Reviewed-by: Chi-Ngai Wan <cnwan@google.com>
diff --git a/bisect_kit/cli.py b/bisect_kit/cli.py
index 5fc8fd5..9c6cf19 100644
--- a/bisect_kit/cli.py
+++ b/bisect_kit/cli.py
@@ -12,6 +12,8 @@
import os
import re
import signal
+import subprocess
+import sys
import textwrap
import time
@@ -265,6 +267,42 @@
return 'exited with code %d' % returncode
+def _execute_command(step, args, env=None, stdout_callback=None):
+ """Helper of do_evaluate() and do_switch().
+
+ Args:
+ step: step name
+ args: command line arguments
+ env: environment variables
+ stdout_callback: Callback function for stdout. Called once per line.
+
+ Returns:
+ returncode; range 0 <= returncode < 128
+
+ Raises:
+ errors.ExecutionFatalError if child process returned fatal error code.
+ """
+ stderr_lines = []
+ p = util.Popen(
+ args,
+ env=env,
+ stdout_callback=stdout_callback,
+ stderr_callback=stderr_lines.append)
+ returncode = p.wait()
+ if returncode < 0 or returncode >= 128:
+ # Only output error messages of child process if it is fatal error.
+ print(
+ 'Last stderr lines of "%s"' % subprocess.list2cmdline(args),
+ file=sys.stderr)
+ print('=' * 40, file=sys.stderr)
+ for line in stderr_lines[-50:]:
+ print(line, end='', file=sys.stderr)
+ print('=' * 40, file=sys.stderr)
+ raise errors.ExecutionFatalError(
+ '%s failed: %s' % (step, format_returncode(returncode)))
+ return returncode
+
+
def do_evaluate(evaluate_cmd, domain, rev):
"""Invokes evaluator command.
@@ -302,15 +340,11 @@
domain.setenv(env, rev)
values = []
- p = util.Popen(
+ returncode = _execute_command(
+ 'eval',
evaluate_cmd,
env=env,
stdout_callback=lambda line: _collect_bisect_result_values(values, line))
- returncode = p.wait()
- if returncode < 0 or returncode >= 128:
- raise errors.ExecutionFatalError(
- 'eval failed: %s' % format_returncode(returncode))
-
if returncode == 0:
return 'old', values
if returncode == 125:
@@ -347,11 +381,7 @@
env['BISECT_REV'] = rev
domain.setenv(env, rev)
- returncode = util.call(*switch_cmd, env=env)
- if returncode < 0 or returncode >= 128:
- raise errors.ExecutionFatalError(
- 'switch failed: %s' % format_returncode(returncode))
-
+ returncode = _execute_command('switch', switch_cmd, env=env)
if returncode != 0:
return 'skip'
return None