NationalSecurityAgency/ghidra · error · LSHException

Unable to find executable

Error message

Unable to find executable

What it means

Thrown by DescriptionManager.findExecutable(String md5) when no ExecutableRecord in the container has an md5 equal to the requested value. The lookup builds a template record from the md5 and uses TreeSet.floor(); if the floor element is null or its md5 does not match, the executable is considered absent.

Source

Thrown at Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/description/DescriptionManager.java:392

	 * @param lhash is a hash indicating where in -src- the call to -dest- is made
	 */
	public void makeCallgraphLink(FunctionDescription src, FunctionDescription dest, int lhash) {
		src.insertCall(dest, lhash);
	}

	/**
	 * Lookup an executable in the container via md5
	 * @param md5 is the md5 to search for
	 * @return return the matching ExecutableRecord
	 * @throws LSHException if the executable cannot be found
	 */
	public ExecutableRecord findExecutable(String md5) throws LSHException {
		ExecutableRecord templ = new ExecutableRecord(md5);
		ExecutableRecord res = exerec.floor(templ);
		if (res != null && res.getMd5().equals(md5)) {
			return res;
		}
		throw new LSHException("Unable to find executable");
	}

	/**
	 * Search for executable based an name, and possibly other qualifying information.
	 * This is relatively inefficient as it just iterates through the list.
	 * @param name is the name that the executable must match
	 * @param arch is null or must match the executable's architecture string
	 * @param comp is null or must match the executable's compiler string
	 * @return the matching executable
	 * @throws LSHException if a matching executable doesn't exist
	 */
	public ExecutableRecord findExecutable(String name, String arch, String comp)
			throws LSHException {
		if (StringUtils.isEmpty(arch)) {
			arch = null;
		}
		if (StringUtils.isEmpty(comp)) {
			comp = null;

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Ensure the ExecutableRecord for the md5 is created (newExecutableRecord/newExecutableLibrary) before calling findExecutable.
  2. Validate the md5 string format and case against the md5Matcher convention used when storing.
  3. Catch LSHException and create the missing executable record on demand if that is the intended workflow.
  4. Confirm the md5 came from the same container/database instance.

Example fix

// before
ExecutableRecord exe = man.findExecutable(md5); // throws if absent

// after
ExecutableRecord exe;
try {
    exe = man.findExecutable(md5);
} catch (LSHException e) {
    exe = man.newExecutableRecord(md5, name, compiler, arch, date, repo, path, null);
}
Defensive patterns

Strategy: try-catch

Try / catch

ExecutableRecord exe;
try {
    exe = man.findExecutable(md5);
} catch (LSHException e) {
    exe = man.newExecutableRecord(md5, name, compiler, arch, date, repo, path, null);
}

Prevention

When it happens

Trigger: Calling findExecutable(md5) with an md5 that is not present in the in-memory DescriptionManager container. Reached during query resolution, transfer, or XML restore when a referenced executable has not been loaded/created yet.

Common situations: Looking up a function before its parent executable was inserted; md5 casing/format mismatch (uppercase vs lowercase hex); referencing an executable from a different BSim database; ordering bug where functions are added before their executables.

Related errors


AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14). Data as JSON: /api/errors/2b830a187d0e16be. Report an issue: GitHub.