fix: handle scp failures and surface ssh stderr in fpga runner branch Wraps the scp subprocess.run(check=True) call in a try/except so a failed copy (bad host, network down, wrong path) logs a clean _LOG.fatal diagnostic and exits 1 instead of propagating a raw CalledProcessError traceback. Also logs the ssh/launch_openocd.sh subprocess's captured stderr (previously discarded), including it in the "no PASS/FAIL sentinel" fatal message so a real remote failure (auth, missing script, wrong path) is diagnosable from the output instead of being silently swallowed behind a generic error.
diff --git a/target/veer/tooling/caliptra_runner.py b/target/veer/tooling/caliptra_runner.py index 4b4c53b..ffeb1c3 100755 --- a/target/veer/tooling/caliptra_runner.py +++ b/target/veer/tooling/caliptra_runner.py
@@ -181,7 +181,13 @@ sys.exit(1) remote_bin = f"/tmp/{Path(image).name}" - subprocess.run(["scp", str(image), f"{host}:{remote_bin}"], check=True) + try: + subprocess.run( + ["scp", str(image), f"{host}:{remote_bin}"], check=True + ) + except subprocess.CalledProcessError as e: + _LOG.fatal("Failed to copy %s to %s: %s", image, host, e) + sys.exit(1) # Loads the image into the MCU ROM backdoor SRAM, deasserts # cptra_ss_rst_b, and streams the debug FIFO back over stdout. @@ -197,6 +203,8 @@ ] _LOG.info("Invoking fpga runner: %s", cmd) proc = subprocess.run(cmd, capture_output=True, text=True, check=False) + if proc.stderr: + _LOG.info("fpga runner stderr: %s", proc.stderr) # Reuse the same Detokenizer mechanism the emulator's tokenized # console path uses (see _detokenizer() above), rather than @@ -205,7 +213,10 @@ text = detokenizer.detokenize_text(proc.stdout) result = scan_output_for_result(text.splitlines()) if result is None: - _LOG.fatal("Device produced no PASS/FAIL sentinel") + _LOG.fatal( + "Device produced no PASS/FAIL sentinel; fpga runner stderr: %s", + proc.stderr, + ) sys.exit(1) sys.exit(result) else: