Hmbown/CodeWhale · error
Android dladdr could not locate the updater's loaded image
Error message
Android dladdr could not locate the updater's loaded image
What it means
On Android, the self-updater needs the filesystem path of its own loaded image and asks the dynamic loader via `dladdr(marker, &info)`, where `marker` is a function pointer inside this binary. A zero return means dladdr could not resolve even that address to a loaded object — typically caused by static linking, symbol stripping, or an unusual loader configuration — so the updater cannot locate the APK/embedded library to replace.
Source
Thrown at crates/cli/src/update.rs:271
#[cfg(target_os = "android")]
fn android_loaded_executable_proof() -> Result<AndroidExecutableProof> {
let marker = android_update_image_marker as *const () as usize as u64;
let dladdr_path = android_dladdr_path(android_update_image_marker as *const libc::c_void)?;
let maps = std::fs::read_to_string(ANDROID_PROC_SELF_MAPS)
.context("failed to read Android executable mappings from /proc/self/maps")?;
android_loaded_executable_proof_report(&maps, marker, &dladdr_path)
}
#[cfg(target_os = "android")]
fn android_dladdr_path(marker: *const libc::c_void) -> Result<PathBuf> {
use std::os::unix::ffi::OsStrExt;
let mut info = std::mem::MaybeUninit::<libc::Dl_info>::zeroed();
// SAFETY: `marker` points to a function in this loaded image and `info`
// points to writable storage for the duration of the call.
let found = unsafe { libc::dladdr(marker, info.as_mut_ptr()) };
if found == 0 {
bail!("Android dladdr could not locate the updater's loaded image");
}
// SAFETY: A non-zero dladdr result initializes `info`.
let info = unsafe { info.assume_init() };
if info.dli_fname.is_null() {
bail!("Android dladdr returned an empty loaded-image path");
}
// SAFETY: `dli_fname` is a NUL-terminated string owned by the dynamic
// loader and remains valid while this image is loaded.
let bytes = unsafe { CStr::from_ptr(info.dli_fname) }.to_bytes();
if bytes.is_empty() {
bail!("Android dladdr returned an empty loaded-image path");
}
Ok(PathBuf::from(OsStr::from_bytes(bytes)))
}
#[cfg(any(target_os = "android", all(test, unix)))]
#[derive(Debug, Clone, PartialEq, Eq)]
struct AndroidImageMapping {View on GitHub (pinned to 0c42157ee5)
Solutions
- Update outside the dladdr path: reinstall/upgrade via your package source (e.g. Termux package manager) instead of self-update
- Rebuild/install an unstripped, dynamically linked codewhale binary on the device and retry self-update
- Report the environment details (device, linker, build flags) upstream — this is an unsupported-loader bug worth filing
Defensive patterns
Strategy: fallback
Validate before calling
#!/usr/bin/env bash # on Android, prefer package-manager updates over self-update if [ "$(uname -o 2>/dev/null || uname)" = "Android" ]; then pkg upgrade codewhale 2>/dev/null || echo "self-update may fail on this loader; use manual install" >&2 else codewhale update fi
Try / catch
# shell: fall back to manual install when self-update cannot locate its image if ! codewhale update; then echo "self-update unavailable; installing verified release manually" >&2 curl -fLO <official-release-url>/codewhale-android-arm64 # verify checksum, then replace the binary on PATH fi
Prevention
- On Android, install codewhale via the package manager and disable self-update
- Keep the deployed binary dynamically linked and unstripped if self-update is required
- Automate updates off-device (download, verify, push) rather than in-place on Android
When it happens
Trigger: Running `codewhale update` in a Termux/proot or embedded Android environment where the binary is statically linked or its symbols are stripped such that dladdr fails on the marker function.
Common situations: Codewhale built with a static/musl-like toolchain on Android; `-s`/strip'd builds; loaders (e.g. certain proot setups) that do not register images with dladdr; hardened environments hiding link maps.
Related errors
- Android dladdr returned an empty loaded-image path
- Android loaded-image authorities resolved to runtime linker
- Android {authority} identifies runtime linker `{}`; refusing
- loaded-image mapping for updater marker is not executable
- loaded-image mapping for updater marker has no file inode
AI-assisted analysis of Hmbown/CodeWhale@0c42157ee5 (2026-08-20).
Data as JSON: /api/errors/be1a85ab6ddf704b.
Report an issue: GitHub.