windmill-labs/windmill · critical

Aborted from C

Error message

Aborted from C

What it means

The Java-to-WASM parser's bundled libc shim defines `abort()` as a `#[no_mangle] extern "C"` stub that immediately panics. It exists only so C-compiled code linking against libc has a symbol for `abort`; the library does not implement (or allow) actual program abortion at runtime. When any code compiled into the WASM module calls `abort()`, the Rust panic unwinds into a `wasm-bindgen`/unreachable trap surfaced as "Aborted from C".

Source

Thrown at backend/parsers/windmill-parser-java/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

  1. Identify which parsed input triggers the abort and minimize it to a small reproducer; it indicates the native component hit an unsupported/invalid state.
  2. Check whether the Java parser version supports the construct/file being parsed and upgrade windmill-parser-java to the latest version.
  3. Validate/sanitize the input before invoking the parser (e.g. confirm it is a well-formed .java/.class artifact).
  4. If reproducible on valid input, file a bug against windmill-parser-java with the reproducer — abort() here is a hard stop with no recovery inside the module.

Example fix

// before: feeding a truncated/corrupted class file straight to the parser
parse(javaBytes);

// after: verify the artifact before parsing
if (!looksLikeValidJavaArtifact(javaBytes)) {
    throw new IllegalArgumentException("input is not a well-formed Java artifact");
}
parse(javaBytes);
Defensive patterns

Strategy: try-catch

Validate before calling

if (!input || input.length === 0) throw new Error('empty parser input');
if (!isWellFormedJavaArtifact(input)) throw new Error('input is not a well-formed Java artifact');

Type guard

function isWellFormedJavaArtifact(b) {
  return typeof b === 'string' || (b instanceof Uint8Array && b.length > 0);
}

Try / catch

try {
  const result = parse(javaInput);
} catch (e) {
  if (String(e).includes('Aborted from C')) {
    // WASM module aborted; treat input as unsupported and fail fast
    throw new ParserUnsupportedInputError(javaInput);
  }
  throw e;
}

Prevention

When it happens

Trigger: Any C (or C-compatible Java-native) code path compiled into the parser's WASM module invokes the C standard library `abort()` — typically after an assertion failure, failed memory allocation, or an internal unreachable branch in the transpiled native code.

Common situations: Parsing a Java source file (or a jar/dependency tree) that drives the embedded C/LLVM-compiled component into an assertion or allocation-failure path; running the WASM parser on input it was never designed to handle; corrupted or truncated class files causing defensive abort() calls in native code.

Related errors


AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03). Data as JSON: /api/errors/e67d927b69db338f. Report an issue: GitHub.