NationalSecurityAgency/ghidra · error · LSHException

Could not (uniquely) match executable

Error message

Could not (uniquely) match executable

What it means

In `fdbQueryChildren`, when no MD5 is supplied, `querySingleExecutable` resolves by name/arch/compiler. A null return -- meaning either no match or a non-unique (ambiguous) match -- causes LSHException("Could not (uniquely) match executable"). The 'uniquely' signals that multiple executables sharing the name cannot be disambiguated.

Source

Thrown at Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/client/AbstractSQLFunctionDatabase.java:2081

	 * @param query the query to execute
	 * @throws LSHException if the database does not track callgraph or the function is not found
	 * @throws SQLException if there is an error issuing the query
	 */
	private void fdbQueryChildren(QueryChildren query) throws LSHException, SQLException {
		if (!info.trackcallgraph) {
			throw new LSHException("Database does not track callgraph");
		}
		ResponseChildren response = query.childrenresponse;
		ExecutableRecord exe = null;

		if (query.md5sum.length() != 0) {
			exe = queryExecutableByMd5(query.md5sum, response.manage);
		}
		else {
			exe = exeTable.querySingleExecutable(response.manage, query.name_exec, query.arch,
				query.name_compiler);
			if (exe == null) {
				throw new LSHException("Could not (uniquely) match executable");
			}
		}
		for (FunctionEntry entry : query.functionKeys) {
			FunctionDescription func =
				queryByNameAddress(response.manage, exe, entry.funcName, entry.address, true);
			if (func == null) {
				throw new LSHException("Could not find function: " + entry.funcName);
			}
			response.correspond.add(func);
		}

		TreeMap<RowKey, FunctionDescription> funcmap = new TreeMap<>();
		response.manage.generateFunctionIdMap(funcmap);
		for (FunctionDescription element : response.correspond) {
			fillinChildren(element, response.manage, funcmap);
		}
	}

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Provide the MD5 (query.md5sum) for an exact, unambiguous match.
  2. Specify arch and name_compiler to disambiguate name-based matches.
  3. Verify the executable exists and is uniquely keyed.

Example fix

// before: name-only, ambiguous across arches
query.name_exec = "myapp";
// after: disambiguate via md5 (preferred) or arch+compiler
query.md5sum = "<exact md5>";
Defensive patterns

Strategy: validation

Validate before calling

// Resolve ambiguity before querying: require md5, or confirm a unique name match.
if (query.md5sum == null || query.md5sum.isEmpty()) {
    int matches = exeTable.countByNameArchCompiler(
        query.name_exec, query.arch, query.name_compiler);
    if (matches != 1) {
        throw new IllegalArgumentException(
            "Executable not uniquely matched (" + matches + "); provide md5");
    }
}

Try / catch

try {
    db.fdbQueryChildren(query);
} catch (LSHException e) {
    if (e.getMessage().equals("Could not (uniquely) match executable")) {
        // ask caller to disambiguate via md5 or arch+compiler
        throw new AmbiguousExecutableException("Provide md5 or arch/compiler", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Querying children by name where either no executable matches, or more than one executable matches the name (different architectures/compilers not disambiguated by the provided fields).

Common situations: Same executable name across architectures; compiler not specified; typo in name; multiple ingested builds of the same program name.

Related errors


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