NationalSecurityAgency/ghidra · error · UnwindException

Cannot find static program for frame ({pc}={pcVal})

Error message

Cannot find static program for frame  ({pc}={pcVal})

What it means

Thrown during stack unwinding when the dynamic program counter value (pcVal) cannot be mapped to any open static program via getProgramLocation(). This UnwindException means there is no trace-to-program mapping that covers the given snapshot and address, so the unwinder cannot translate the live PC into a static address for analysis.

Source

Thrown at Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/stack/StackUnwinder.java:326

	/**
	 * Compute the unwind information for the given program counter and context
	 * 
	 * <p>
	 * For the most part, this just translates the dynamic program counter to a static program
	 * address and then invokes {@link UnwindAnalysis#computeUnwindInfo(Address, TaskMonitor)}.
	 * 
	 * @param snap the snapshot key (used for mapping the program counter to a program database)
	 * @param pcVal the program counter (dynamic)
	 * @param monitor a monitor for cancellation
	 * @return the unwind info, possibly incomplete
	 * @throws CancelledException if the monitor is cancelled
	 */
	public StaticAndUnwind computeUnwindInfo(long snap, Address pcVal,
			TaskMonitor monitor) throws CancelledException {
		// TODO: Try markup in trace first?
		ProgramLocation staticPcLoc = getProgramLocation(snap, pcVal);
		if (staticPcLoc == null) {
			throw new UnwindException(
				"Cannot find static program for frame  (" + pc + "=" + pcVal + ")");
		}
		Program program = staticPcLoc.getProgram();
		Address staticPc = staticPcLoc.getAddress();
		try {
			UnwindInfo info = service.getUnwindInfo(program, staticPc, monitor);
			StaticAndUnwind sau = new StaticAndUnwind(staticPc, info);
			if (sau.info().ofReturn() == null) {
				Function function = sau.info().function();
				if (function != null) {
					Address ep = function.getEntryPoint();
					UnwindInfo epInfo = service.getUnwindInfo(program, ep, monitor);
					info = new UnwindInfo(info.function(), info.depth(),
						info.adjust(), epInfo.ofReturn(), epInfo.maskOfReturn(), info.saved(),
						info.warnings(), info.error());
					sau = new StaticAndUnwind(staticPc, info);
				}
			}

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Open the static program that corresponds to the debug target in the Ghidra tool.
  2. Configure or re-establish the trace-to-program mapping (Debugger > Mappings) to cover the PC's address range.
  3. Verify the snapshot (snap) being used corresponds to a state where mappings are valid.
  4. If debugging dynamically loaded code, map the module's memory region to its imported program.

Example fix

// No code fix; ensure a valid mapping exists:
// Debugger tool > Window > Mappings > add/verify mapping from trace space to static program.
Defensive patterns

Strategy: validation

Validate before calling

// Check that a static program location can be found before computing unwind info:
ProgramLocation staticPcLoc = getProgramLocation(snap, pcVal);
if (staticPcLoc == null) {
    // inform user: no mapping for this PC; skip frame or set up mapping
}

Type guard

private boolean hasStaticMapping(long snap, Address pcVal) {
    return getProgramLocation(snap, pcVal) != null;
}

Try / catch

try {
    StaticAndUnwind sau = unwinder.computeUnwindInfo(snap, pcVal, monitor);
} catch (UnwindException e) {
    if (e.getMessage().startsWith("Cannot find static program")) {
        // mapping missing — prompt user to configure trace-to-program mapping
    } else { throw e; }
}

Prevention

When it happens

Trigger: StackUnwinder.computeUnwindInfo() calls getProgramLocation(snap, pcVal) which returns null. This happens when no mapping service entry covers the PC's address space at the given snapshot, when the target program is not open in the tool, or when the trace's memory regions were never mapped to a static program.

Common situations: The developer started debugging without opening the corresponding static program. The address space mapping was never set up between the trace and the program. The program was closed or the mapping was invalidated after a session reload. Debugging a region of memory (e.g., JIT code, dynamically loaded library) that has no corresponding static program.

Related errors


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