oracle/graal · critical

[eden #%ld] FATAL ERROR

Error message

[eden #%ld] FATAL ERROR 

What it means

In eden.c (the native library that gives each Espresso context its own linker namespace via dlmopen), FATAL is a macro that prints '[eden #<ns>] FATAL ERROR <msg>' to stderr and calls exit(-1), killing the whole process. It is used when an unrecoverable native invariant fails (e.g. glibc symbol resolution or namespace setup).

Source

Thrown at espresso/src/com.oracle.truffle.espresso.eden/src/eden.c:47

#include <unistd.h>
#include <dlfcn.h>

#include <gnu/libc-version.h>

#define UNINITIALIZED ((void*) ~0)

extern void *__libc_dlsym(void *handle, const char *symbol);
extern void *__libc_dlopen_mode(const char *filename, int flags);
extern const unsigned short int ** __ctype_b_loc (void);

// Linking namespace where this library is loaded.
static Lmid_t namespace_id = 0;

// Debug flags, can be set with EDEN_DEBUG=true|1
static int eden_debug = 0;

#define LOG(fmt, ...) do { if (eden_debug) fprintf(stderr, "[eden #%ld] " fmt, namespace_id, ##__VA_ARGS__); } while (0)
#define FATAL(fmt, ...) do { fprintf(stderr, "[eden #%ld] FATAL ERROR " fmt, namespace_id, ##__VA_ARGS__); exit(-1); } while (0)

static int glibc_major = 0;
static int glibc_minor = 0;

static void *real_dlopen(const char *filename, int flags) {
    LOG("real_dlopen(%s, %d)\n", filename, flags);
    static void *(*the_real_dlopen)(const char *, int) = NULL;
    if (the_real_dlopen == NULL) {
        LOG("dlsym(RTLD_NEXT, dlopen)\n");
        the_real_dlopen = dlsym(RTLD_NEXT, "dlopen");
        LOG("dlsym(RTLD_NEXT, dlopen) => %p\n", the_real_dlopen);
    }
    void *result = the_real_dlopen(filename, flags);
    LOG("real_dlopen(%s, %d) => %p\n", filename, flags, result);
    return result;
}

static void *get_libc() {

View on GitHub (pinned to a66e9ccd1d)

Solutions

  1. Set EDEN_DEBUG=true (or 1) to get the LOG trace before the fatal and identify which lookup failed.
  2. Run on a standard glibc distribution (not musl/Alpine) with a supported glibc version.
  3. Raise limits on namespaces/threads if many contexts are used; reduce concurrent contexts loading native libs.
  4. Report the FATAL message plus glibc version and repro to the GraalVM issue tracker.
Defensive patterns

Strategy: try-catch

Validate before calling

// Eden cannot be caught (exit(-1)); validate the environment instead
// run on glibc, check RLIMIT/namespace limits before creating many contexts

Prevention

When it happens

Trigger: Eden's FATAL sites: glibc version detection failing, __libc_dlopen_mode/dlsym lookup failures, or dlmopen namespace limits (RLIMIT/NSS module loading) when creating many contexts with isolated native libraries.

Common situations: Running many Espresso contexts each loading native libraries (per-context linker namespaces); restrictive container seccomp/rlimits; unusual glibc versions (musl-based images are unsupported); LD_PRELOAD interposition breaking dlsym(RTLD_NEXT, ...).

Related errors


AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14). Data as JSON: /api/errors/fa46489d440aa401. Report an issue: GitHub.