{"record":{"id":"fa46489d440aa401","repo":"oracle/graal","slug":"eden-ld-fatal-error","errorCode":null,"errorMessage":"[eden #%ld] FATAL ERROR ","messagePattern":"\\[eden #%ld\\] FATAL ERROR ","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"espresso/src/com.oracle.truffle.espresso.eden/src/eden.c","lineNumber":47,"sourceCode":"#include <unistd.h>\n#include <dlfcn.h>\n\n#include <gnu/libc-version.h>\n\n#define UNINITIALIZED ((void*) ~0)\n\nextern void *__libc_dlsym(void *handle, const char *symbol);\nextern void *__libc_dlopen_mode(const char *filename, int flags);\nextern const unsigned short int ** __ctype_b_loc (void);\n\n// Linking namespace where this library is loaded.\nstatic Lmid_t namespace_id = 0;\n\n// Debug flags, can be set with EDEN_DEBUG=true|1\nstatic int eden_debug = 0;\n\n#define LOG(fmt, ...) do { if (eden_debug) fprintf(stderr, \"[eden #%ld] \" fmt, namespace_id, ##__VA_ARGS__); } while (0)\n#define FATAL(fmt, ...) do { fprintf(stderr, \"[eden #%ld] FATAL ERROR \" fmt, namespace_id, ##__VA_ARGS__); exit(-1); } while (0)\n\nstatic int glibc_major = 0;\nstatic int glibc_minor = 0;\n\nstatic void *real_dlopen(const char *filename, int flags) {\n    LOG(\"real_dlopen(%s, %d)\\n\", filename, flags);\n    static void *(*the_real_dlopen)(const char *, int) = NULL;\n    if (the_real_dlopen == NULL) {\n        LOG(\"dlsym(RTLD_NEXT, dlopen)\\n\");\n        the_real_dlopen = dlsym(RTLD_NEXT, \"dlopen\");\n        LOG(\"dlsym(RTLD_NEXT, dlopen) => %p\\n\", the_real_dlopen);\n    }\n    void *result = the_real_dlopen(filename, flags);\n    LOG(\"real_dlopen(%s, %d) => %p\\n\", filename, flags, result);\n    return result;\n}\n\nstatic void *get_libc() {","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/oracle/graal/blob/a66e9ccd1d7bf2552883939aa0788dfd0e294aab/espresso/src/com.oracle.truffle.espresso.eden/src/eden.c#L29-L65","documentation":"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).","triggerScenarios":"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.","commonSituations":"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, ...).","solutions":["Set EDEN_DEBUG=true (or 1) to get the LOG trace before the fatal and identify which lookup failed.","Run on a standard glibc distribution (not musl/Alpine) with a supported glibc version.","Raise limits on namespaces/threads if many contexts are used; reduce concurrent contexts loading native libs.","Report the FATAL message plus glibc version and repro to the GraalVM issue tracker."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Eden cannot be caught (exit(-1)); validate the environment instead\n// run on glibc, check RLIMIT/namespace limits before creating many contexts","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Run on standard glibc distros; avoid musl/Alpine for eden-based isolation.","Set EDEN_DEBUG=true when diagnosing to capture the LOG trace before a FATAL.","Limit the number of concurrent contexts that load native libraries."],"tags":["espresso","eden","native","dlmopen","process-exit"],"backgroundTag":null,"analyzedSha":"a66e9ccd1d7bf2552883939aa0788dfd0e294aab","analyzedAt":"2026-08-14T13:58:47.161Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}