Hmbown/CodeWhale · error

Android loaded-image authorities disagree: dladdr resolved…

Error message

Android loaded-image authorities disagree: dladdr resolved to {}, but /proc/self/maps resolved to {}

What it means

The Android self-update proof cross-checks two independent authorities for the location of the running executable: dladdr (the dynamic linker's answer for the object containing the marker function) and the /proc/self/maps row covering the same address. After canonicalizing both paths, if they differ the updater cannot prove which file it is actually running from and refuses to proceed, since replacing the wrong file could corrupt an unrelated binary.

Solutions

  1. Check whether the binary path involves symlinks or bind mounts; run the update from the canonical, real path of the executable.
  2. Re-run the updater after re-installing the binary so dladdr and /proc/self/maps refer to the same inode; do not replace the binary underneath a running process.
  3. Verify the filesystem supports canonicalization consistently (avoid overlayfs quirks or FUSE mounts that report different paths).
  4. If it persists, capture the two reported paths from the error message and file a bug with that output.

Example fix

// before: running updater through a symlink
$PREFIX/bin/codewhale update   # $PREFIX/bin/codewhale -> /data/.../bin/codewhale.real
// after: run the real path directly
/data/app/.../bin/codewhale.real update
Defensive patterns

Strategy: validation

Validate before calling

let via_dladdr = std::fs::canonicalize(dladdr_path)?;
let via_maps = std::fs::canonicalize(maps_path)?;
if via_dladdr != via_maps {
    eprintln!("authority mismatch: {via_dladdr:?} vs {via_maps:?}; refusing self-update");
    return Err(anyhow!("loaded-image authorities disagree"));
}

Try / catch

match run_update() {
    Err(e) if e.to_string().contains("authorities disagree") => {
        // fall back to manual install instructions
    }
    other => other?,
}

Prevention

When it happens

Trigger: android_loaded_executable_proof (during self-update) when canonicalize() of the dladdr-reported path and the maps-reported path yield different absolute paths for the same marker address.

Common situations: Symlink or bind-mount setups where one authority reports the symlink path and the other the real path outside the resolver's view; running from an overlay/twerged filesystem where canonicalization diverges; a stale maps row after the binary was replaced mid-run.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/3b95d3a2d9024b79. Report an issue: GitHub.

Appendix: source

Thrown at crates/cli/src/update.rs:449

) -> Result<AndroidExecutableProof> {
    let mapping = parse_android_image_mapping(maps, marker)?;
    validate_android_reported_path("dladdr", dladdr_path)?;
    validate_android_reported_path("/proc/self/maps", &mapping.path)?;

    let resolved_dladdr = dladdr_path.canonicalize().with_context(|| {
        format!(
            "failed to canonicalize Android dladdr path {}",
            dladdr_path.display()
        )
    })?;
    let resolved_mapping = mapping.path.canonicalize().with_context(|| {
        format!(
            "failed to canonicalize Android loaded-image mapping {}",
            mapping.path.display()
        )
    })?;
    if resolved_dladdr != resolved_mapping {
        bail!(
            "Android loaded-image authorities disagree: dladdr resolved to {}, but /proc/self/maps resolved to {}",
            resolved_dladdr.display(),
            resolved_mapping.display()
        );
    }
    if is_android_linker_name(&resolved_mapping) {
        bail!(
            "Android loaded-image authorities resolved to runtime linker {}; refusing to use the linker as an update target",
            resolved_mapping.display()
        );
    }
    if !is_executable_file(&resolved_mapping) {
        bail!(
            "Android loaded image `{}` is not an executable regular file; refusing to select an update target",
            resolved_mapping.display()
        );
    }

View on GitHub (pinned to 73e0f67d83)