Skip to content

Commit 9645df9

Browse files
committed
Detect kernel crash before connection and capture stderr
- Check if kernel process has exited before attempting ZMQ connections - Capture and report kernel stderr on early crash - Add CI debug step that tries to launch kernel directly with 5s timeout
1 parent bc7dfa6 commit 9645df9

2 files changed

Lines changed: 33 additions & 3 deletions

File tree

.github/workflows/conformance.yml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -243,8 +243,12 @@ jobs:
243243
echo "Binary: $KERNEL_BIN"
244244
ls -la "$KERNEL_BIN" 2>/dev/null || echo "Binary not found at $KERNEL_BIN"
245245
which xoctave 2>/dev/null || echo "xoctave not in PATH"
246-
echo "=== Try running ==="
247-
ldd "$KERNEL_BIN" 2>/dev/null | grep "not found" || echo "All libraries found (or not an ELF binary)"
246+
echo "=== ldd ==="
247+
ldd "$KERNEL_BIN" 2>/dev/null || echo "ldd failed"
248+
echo "=== Try launching kernel directly (5s timeout) ==="
249+
# Create a dummy connection file to see if kernel starts
250+
echo '{"transport":"tcp","ip":"127.0.0.1","shell_port":0,"iopub_port":0,"stdin_port":0,"control_port":0,"hb_port":0,"signature_scheme":"hmac-sha256","key":"test"}' > /tmp/test-conn.json
251+
timeout 5 xvfb-run -a "$KERNEL_BIN" -f /tmp/test-conn.json 2>&1 || echo "Kernel exited with code $?"
248252
echo "=== env ==="
249253
echo "PATH=$PATH"
250254
echo "LD_LIBRARY_PATH=${LD_LIBRARY_PATH:-unset}"

src/harness.rs

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,14 +111,40 @@ impl KernelUnderTest {
111111
tokio::fs::write(&connection_path, content).await?;
112112

113113
// Launch kernel process (capture stderr for diagnostics)
114-
let process = kernelspec
114+
let mut process = kernelspec
115115
.command(&connection_path, Some(Stdio::null()), Some(Stdio::piped()))?
116116
.spawn()
117117
.map_err(|e| HarnessError::LaunchFailed(e.to_string()))?;
118118

119119
// Give kernel time to start
120120
tokio::time::sleep(Duration::from_millis(2000)).await;
121121

122+
// Check if kernel process has already exited (crashed during startup)
123+
match process.try_wait() {
124+
Ok(Some(exit_status)) => {
125+
// Process has already exited - read stderr for diagnostics
126+
let mut stderr_output = String::new();
127+
if let Some(stderr) = process.stderr.take() {
128+
use tokio::io::AsyncReadExt;
129+
let mut reader = tokio::io::BufReader::new(stderr);
130+
let _ = reader.read_to_string(&mut stderr_output).await;
131+
}
132+
let msg = if stderr_output.is_empty() {
133+
format!("Kernel process exited with {} before connections could be established", exit_status)
134+
} else {
135+
format!("Kernel process exited with {} before connections could be established. Stderr:\n{}", exit_status, stderr_output)
136+
};
137+
eprintln!("{}", msg);
138+
return Err(HarnessError::LaunchFailed(msg));
139+
}
140+
Ok(None) => {
141+
// Process still running - good
142+
}
143+
Err(e) => {
144+
eprintln!("Warning: could not check kernel process status: {}", e);
145+
}
146+
}
147+
122148
// Create peer identity for shell/stdin (must share identity)
123149
let identity = peer_identity_for_session(&session_id)?;
124150

0 commit comments

Comments
 (0)