{"record":{"id":"91ddcfdfdb06bee9","repo":"benfred/py-spy","slug":"both-python-and-libpython-are-invalid","errorCode":null,"errorMessage":"Both python and libpython are invalid.","messagePattern":"Both python and libpython are invalid\\.","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"src/python_process_info.rs","lineNumber":439,"sourceCode":"    // try scanning the BSS section of the binary for things that might be the interpreterstate\n    let err = if let Some(ref pb) = python_info.python_binary {\n        match get_interpreter_address_from_binary(pb, &*python_info.maps, process, version) {\n            Ok(addr) => return Ok(addr),\n            err => Some(err),\n        }\n    } else {\n        None\n    };\n\n    // Before giving up, try again if there is a libpython.so\n    if let Some(ref lpb) = python_info.libpython_binary {\n        info!(\"Failed to get interpreter from binary BSS, scanning libpython BSS\");\n        match get_interpreter_address_from_binary(lpb, &*python_info.maps, process, version) {\n            Ok(addr) => Ok(addr),\n            lib_err => err.unwrap_or(lib_err),\n        }\n    } else {\n        err.expect(\"Both python and libpython are invalid.\")\n    }\n}\n\n// Gets the address of the main PyInterpreterState object from loaded symbols\nfn get_interpreter_address_from_symbols<P>(\n    python_info: &PythonProcessInfo,\n    process: &P,\n    version: &Version,\n) -> Result<usize, Error>\nwhere\n    P: ProcessMemory,\n{\n    match version {\n        Version {\n            major: 3,\n            minor: 13..=14,\n            ..\n        } => {","sourceCodeStart":421,"sourceCodeEnd":457,"githubUrl":"https://github.com/benfred/py-spy/blob/32080cc0c22bc23938541dfa7dabb6090e40be14/src/python_process_info.rs#L421-L457","documentation":"In get_interpreter_address, py-spy tries to locate the PyInterpreterState address first from the python binary's BSS and then from libpython's BSS. If both attempts return errors, err.expect() panics with \"Both python and libpython are invalid.\", meaning memory scanning for the interpreter state failed on every candidate module.","triggerScenarios":"Attaching to a Python process where neither the main binary nor libpython yielded a valid interpreter address from BSS scanning — e.g. statically linked/ref-linked python, unusual builds, or restricted memory reads, when called from PythonSpy::new during dump/record.","commonSituations":"Profiling Python builds compiled without dynamic libpython or with nonstandard layouts, custom/embedded interpreters, selinux/ptrace restrictions causing failed memory reads, or version-mismatched py-spy vs an unusual Python version.","solutions":["Upgrade py-spy to the latest version — support for new Python versions and build layouts is added over time.","Check for ptrace/memory-read restrictions (e.g. /proc/sys/kernel/yama/ptrace_scope, SELinux) and relax them or run as root.","Try profiling a stock interpreter build of the same Python version to confirm the custom build is the cause.","Fall back to sampling mode `py-spy record` with --nonblocking, or use a different profiler (e.g. pyinstrument in-process) if scanning can't work for that binary."],"exampleFix":"// before: custom python build, old py-spy\npy-spy dump --pid 1234  # panic: Both python and libpython are invalid.\n// after\ncargo install py-spy --locked  # or pip install py-spy --upgrade\nsudo py-spy dump --pid 1234","handlingStrategy":"fallback","validationCode":"# preflight: confirm a stock interpreter works on this host\npy-spy dump --pid $(pgrep -f 'python3 -c .*idle_probe' || pgrep -x python3 | head -1) >/dev/null \\\n  || echo 'py-spy attach may be unsupported for this python build'","typeGuard":null,"tryCatchPattern":"# attempt py-spy, fall back to an in-process profiler\nsudo py-spy record --pid \"$PID\" -o p.svg || \\\n  python -m pyinstrument --renderer html -o p.html script.py","preventionTips":["Keep py-spy updated to the newest release for new Python version support.","Avoid profiling custom/statically-linked Python builds; use stock interpreters for production.","Check ptrace/SELinux restrictions (yama ptrace_scope) and run py-spy as root when attaching."],"tags":["memory-scan","interpreter","python-internals","attach"],"backgroundTag":"interpreter-address-not-found","analyzedSha":"32080cc0c22bc23938541dfa7dabb6090e40be14","analyzedAt":"2026-09-05T19:30:55.142Z","contentChangedAt":"2026-09-05T19:30:55.142Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}