{"record":{"id":"5447bbe938fd45ea","repo":"Hmbown/CodeWhale","slug":"android-dladdr-returned-an-empty-loaded-image-path","errorCode":null,"errorMessage":"Android dladdr returned an empty loaded-image path","messagePattern":"Android dladdr returned an empty loaded-image path","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/cli/src/update.rs","lineNumber":276,"sourceCode":"        .context(\"failed to read Android executable mappings from /proc/self/maps\")?;\n    android_loaded_executable_proof_report(&maps, marker, &dladdr_path)\n}\n\n#[cfg(target_os = \"android\")]\nfn android_dladdr_path(marker: *const libc::c_void) -> Result<PathBuf> {\n    use std::os::unix::ffi::OsStrExt;\n\n    let mut info = std::mem::MaybeUninit::<libc::Dl_info>::zeroed();\n    // SAFETY: `marker` points to a function in this loaded image and `info`\n    // points to writable storage for the duration of the call.\n    let found = unsafe { libc::dladdr(marker, info.as_mut_ptr()) };\n    if found == 0 {\n        bail!(\"Android dladdr could not locate the updater's loaded image\");\n    }\n    // SAFETY: A non-zero dladdr result initializes `info`.\n    let info = unsafe { info.assume_init() };\n    if info.dli_fname.is_null() {\n        bail!(\"Android dladdr returned an empty loaded-image path\");\n    }\n    // SAFETY: `dli_fname` is a NUL-terminated string owned by the dynamic\n    // loader and remains valid while this image is loaded.\n    let bytes = unsafe { CStr::from_ptr(info.dli_fname) }.to_bytes();\n    if bytes.is_empty() {\n        bail!(\"Android dladdr returned an empty loaded-image path\");\n    }\n    Ok(PathBuf::from(OsStr::from_bytes(bytes)))\n}\n\n#[cfg(any(target_os = \"android\", all(test, unix)))]\n#[derive(Debug, Clone, PartialEq, Eq)]\nstruct AndroidImageMapping {\n    start: u64,\n    end: u64,\n    device_major: u32,\n    device_minor: u32,\n    inode: u64,","sourceCodeStart":258,"sourceCodeEnd":294,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/0c42157ee52f9d55af2b506d71b46249910f77d3/crates/cli/src/update.rs#L258-L294","documentation":"The successor case to a failed dladdr: the call succeeded, but `dli_fname` is null or points at an empty string, so there is no usable path for the loaded image. Both the null check and the empty-bytes check after `CStr::from_ptr` raise this same message. It means the loader resolved the object but declined to name its file — seen with APK-embedded native libraries loaded through nonstandard paths.","triggerScenarios":"Running `codewhale update` on Android where the binary lives inside an APK/lib directory or is loaded via a file descriptor / memfd, leaving `dli_fname` empty; loader configurations that anonymize image paths.","commonSituations":"Codewhale bundled as an nativeLibrary in an Android app; execution from content-provider or fd-based mounts; some proot/chroot sandboxes that blank out link-map names.","solutions":["Skip self-update on this platform: install/upgrade via the package manager or by replacing the binary manually with a verified release asset","Run codewhale from a real filesystem path (extract from APK to $PREFIX/bin) so the loader can name the image, then retry update","File an upstream report with the Android loader details so the path-resolution strategy can be extended"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"#!/usr/bin/env bash\n# dladdr cannot name APK-embedded images; ensure codewhale runs from a real path\nbin=\"$PREFIX/bin/codewhale\"\n[ -x \"$bin\" ] || { echo \"install codewhale to $bin before using self-update\" >&2; exit 1; }\ncodewhale update","typeGuard":null,"tryCatchPattern":"# shell: fall back to verified manual replacement\nif ! codewhale update; then\n  curl -fLO <official-release-url>/codewhale-android-arm64\n  sha256sum -c checksums.txt --ignore-missing && install -m 0755 codewhale-android-arm64 \"$PREFIX/bin/codewhale\"\nfi","preventionTips":["Run the binary from a conventional filesystem path (e.g. $PREFIX/bin), not from inside an APK or fd-based mount","Use off-device update pipelines on Android; treat in-place self-update as best-effort"],"tags":["android","dladdr","self-update","dli-fname","platform","linker"],"backgroundTag":"dladdr-failed","analyzedSha":"0c42157ee52f9d55af2b506d71b46249910f77d3","analyzedAt":"2026-08-20T21:50:45.477Z","schemaVersion":2},"datasetVersion":"2026-08-22T04:17:13.399Z"}