windmill-labs/windmill · error
Aborted from C
Error message
Aborted from C
What it means
The windmill-parser-r WASM module provides abort() as a libc shim that panics with "Aborted from C". When the C code compiled into the parser (tree-sitter runtime or scanner) calls abort(), the panic converts the C abort into a Rust panic that terminates the parse. This is a deliberate translation: the WASM sandbox has no real libc, so abort cannot actually terminate a process.
Source
Thrown at backend/parsers/windmill-parser-r/src/wasm_libc.rs:15
use std::collections::BTreeMap;
use std::sync::{Mutex, OnceLock};
use std::{
alloc::{self, Layout},
ffi::{c_char, c_int, c_void},
mem::align_of,
ptr,
};
use wasm_bindgen::prelude::*;
/* -------------------------------- stdlib.h -------------------------------- */
#[no_mangle]
pub unsafe extern "C" fn abort() {
panic!("Aborted from C");
}
macro_rules! console_log {
($($t:tt)*) => (unsafe { log(&format_args!($($t)*).to_string()) })
}
#[wasm_bindgen]
extern "C" {
#[wasm_bindgen(js_namespace = console)]
fn log(a: &str);
}
#[no_mangle]
pub unsafe extern "C" fn malloc(size: usize) -> *mut c_void {
if size == 0 {
return ptr::null_mut();
}
View on GitHub (pinned to e474e8803c)
Solutions
- Identify which C call site invokes abort() by building the parser with debug symbols or instrumenting the shim to log a wasm backtrace before panicking.
- Validate/normalize the R input being parsed; try a minimal snippet to find the construct that trips the abort.
- Check for an earlier panic in the same parse (fprintf/snprintf/clock stubs) that left state inconsistent — fix that root cause.
- Align the tree-sitter runtime and grammar versions so scanner and runtime ABIs match.
Example fix
// before (wasm_libc.rs)
#[no_mangle]
pub unsafe extern "C" fn abort() {
panic!("Aborted from C");
}
// after — log a backtrace before panicking to find the C call site
#[no_mangle]
pub unsafe extern "C" fn abort() {
console_log!("abort() called from C");
panic!("Aborted from C");
} Defensive patterns
Strategy: try-catch
Validate before calling
// Guard the entry point and isolate each parse:
function prepareDoc(src) {
if (typeof src !== 'string' || src.length === 0) {
throw new TypeError('expected non-empty string document');
}
return src;
} Type guard
function isNonEmptyString(v) {
return typeof v === 'string' && v.length > 0;
} Try / catch
try {
const tree = parser.parse(prepareDoc(src));
return tree;
} catch (e) {
if (String(e).includes('Aborted from C')) {
// C-level abort: recreate the parser and treat this document as unparseable
parser = new Parser();
return null;
}
throw e;
} Prevention
- Instrument the abort shim to capture a wasm backtrace so the C call site is identifiable on first occurrence.
- Bisect the failing document down to a minimal snippet and report it to the grammar maintainers.
- Keep the tree-sitter runtime and grammar versions in lockstep; ABI mismatch is a classic abort source.
- Treat any earlier shim panic in the same parse as the likely root cause — fix upstream stubs, not the abort itself.
When it happens
Trigger: Any C code path in the R parser that calls abort(): failed internal invariant checks in the tree-sitter C runtime, custom scanner error handling that gives up, or an assertion path that funnels into abort() instead of __assert_fail.
Common situations: Parsing pathological or very large R input that drives the grammar into an unexpected state; a scanner version mismatch with the tree-sitter runtime ABI; memory corruption earlier in the parse (e.g. from an incomplete shim such as a panicking fprintf/snprintf) that later triggers abort.
Related errors
AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03).
Data as JSON: /api/errors/1ad25eac2ecab1cb.
Report an issue: GitHub.