NationalSecurityAgency/ghidra · error · UnwindException
Cannot compute stack address for offset %d.\nFrame error: %s
Error message
Cannot compute stack address for offset %d.\nFrame error: %s
What it means
AnalysisUnwoundFrame.applyBase() computes a stack address from an offset by adding it to the frame's base. When base == null the frame's stack base could not be determined (the analysis recorded an error in info.error()), so applyBase throws UnwindException("Cannot compute stack address for offset %d.\nFrame error: %s") chaining the original analysis error. This propagates during variable/storage evaluation that needs a stack base.
Source
Thrown at Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/stack/AnalysisUnwoundFrame.java:138
* proceeds the same as the starting frame.
*
* @param monitor a monitor for cancellation
* @return the next frame up
* @throws CancelledException if the monitor is cancelled
* @throws UnwindException if unwinding fails
*/
public AnalysisUnwoundFrame<WatchValue> unwindNext(TaskMonitor monitor)
throws CancelledException {
if (info == null || info.ofReturn() == null) {
throw new NoSuchElementException();
}
return unwinder.getFrame(coordinates, state, level + 1, null, monitor);
}
@Override
protected Address applyBase(long offset) {
if (base == null) {
throw new UnwindException("Cannot compute stack address for offset %d.\nFrame error: %s"
.formatted(offset, info.error().getMessage()),
info.error());
}
return base.add(offset);
}
@Override
protected SavedRegisterMap computeRegisterMap() {
return registerMap;
}
@Override
protected Address computeAddressOfReturnAddress() {
return info.ofReturn(base);
}
@Override
public Address getReturnAddress() {View on GitHub (pinned to d5f144c24d)
Solutions
- Inspect the chained cause (info.error()) to fix the underlying analysis problem (e.g. recover SP, provide annotations).
- Catch UnwindException around frame/variable evaluation and skip the frame that lacks a base.
- Improve symbol/annotation data so the unwinder can compute the base (re-analyze, fix function signatures).
- Stop unwinding at the frame where analysis failed rather than descending further.
Example fix
// before
Address sa = frame.applyBase(offset); // throws UnwindException: base==null
// after
try {
Address sa = frame.applyBase(offset);
} catch (UnwindException e) {
Msg.warn(this, "Stack base unavailable for frame; skipping: " + e.getCause());
return null;
} Defensive patterns
Strategy: try-catch
Validate before calling
// No purely local check; base==null stems from failed analysis. Best pre-check:
// confirm analysis produced a base before evaluating variables relative to it.
if (frame.getBase() == null) { // if a getter exists
// do not call applyBase; skip frame or re-analyze
} Try / catch
try {
Address sa = frame.applyBase(offset);
} catch (UnwindException e) {
// e.getCause() is the original analysis error (info.error())
// skip this frame or fix the underlying analysis
} Prevention
- Stop unwinding at frames whose analysis failed rather than descending further.
- Improve function signatures/annotations so SP/base can be recovered.
- Inspect the chained cause to address the real analysis failure.
When it happens
Trigger: Unwinding a frame whose stack-pointer/base analysis failed (e.g. could not recover SP, missing or unreliable saved registers). Evaluating variables relative to a base that was never computed. Deeper frames past a frame that failed analysis.
Common situations: Stripped or optimized binaries where SP recovery is unreliable. Frames where the unwinder could not find a return address or stack-adjustment info. Corrupt or incomplete decompilation/stack annotations.
Related errors
- Cannot map %s:%s to dynamic adress
- Return address must be in {}
- Return address must be in {}
- The program counter reference is missing for the frame!
- The program containing the frame's function is unavailable,
AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14).
Data as JSON: /api/errors/114dba6127da5db7.
Report an issue: GitHub.