NationalSecurityAgency/ghidra · error · IllegalArgumentException
Cannot have instructions steps following p-code steps
Error message
Cannot have instructions steps following p-code steps
What it means
TraceSchedule.advanced combines this schedule with a 'next' schedule to produce a continued schedule. If this schedule already has p-code steps (pSteps is non-empty), and the next schedule has instruction/tick steps (steps is non-empty), the combination is illegal — p-code steps cannot be followed by instruction steps because that would require emulating backwards from p-code to instruction level. Only p-code-after-p-code or instruction-after-instruction continuations are valid.
Source
Thrown at Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/model/time/schedule/TraceSchedule.java:892
* schedule contains any p-code steps and {@code next} has instruction steps, an error will be
*
* @param next the schedule to append. Its snap is ignored.
* @return the complete schedule
* @throws IllegalArgumentException if the result would have instruction steps following p-code
* steps
*/
public TraceSchedule advanced(TraceSchedule next) {
if (this.pSteps.isNop()) {
Sequence ticks = this.steps.clone();
ticks.advance(next.steps);
return new TraceSchedule(this.snap, ticks, next.pSteps.clone(), next.source);
}
else if (next.steps.isNop()) {
Sequence pTicks = this.pSteps.clone();
pTicks.advance(next.pSteps);
return new TraceSchedule(this.snap, this.steps.clone(), pTicks, Source.INPUT);
}
throw new IllegalArgumentException("Cannot have instructions steps following p-code steps");
}
/**
* Drop the p-code steps
*
* @return the schedule without ops
*/
public TraceSchedule dropPSteps() {
return new TraceSchedule(this.snap, this.steps, new Sequence());
}
/**
* Drop the last step
*
* <p>
* If there are p-code steps, this drops the last step there. Otherwise, this drops the last
* step from the instruction steps. A step includes all ticks in the step, e.g.,
* {@code 0:t0-20;t1-5} becomes {@code 0:t0-20}. To remove a specific number of ticks, seeView on GitHub (pinned to d5f144c24d)
Solutions
- If this schedule has pSteps, only advance with a next schedule that also has only pSteps (next.steps must be nop)
- Drop the pSteps from this schedule first: schedule = schedule.dropPSteps(), then advance
- Restructure the schedule so all instruction steps come before all p-code steps
- Use schedule.finishPcodeStep() or equivalent to normalize before advancing
Example fix
// before
TraceSchedule base = TraceSchedule.parse("0:t1-5.t2-1", Source.INPUT, TimeRadix.DEC);
TraceSchedule next = TraceSchedule.parse("0:t1-3", Source.INPUT, TimeRadix.DEC);
TraceSchedule combined = base.advanced(next); // throws
// after
TraceSchedule base = TraceSchedule.parse("0:t1-5.t2-1", Source.INPUT, TimeRadix.DEC);
TraceSchedule next = TraceSchedule.parse("0:.t2-1", Source.INPUT, TimeRadix.DEC); // pSteps only
TraceSchedule combined = base.advanced(next); Defensive patterns
Strategy: validation
Validate before calling
boolean canAdvance(TraceSchedule base, TraceSchedule next) {
if (!base.pSteps.isNop() && !next.steps.isNop()) {
return false; // instruction steps after p-code steps
}
return true;
} Type guard
// N/A
Try / catch
try {
TraceSchedule combined = base.advanced(next);
} catch (IllegalArgumentException e) {
// drop pSteps and retry, or restructure the schedule
TraceSchedule combined = base.dropPSteps().advanced(next);
} Prevention
- Never mix instruction steps after p-code steps in a schedule
- Check base.pSteps.isNop() or next.steps.isNop() before calling advanced
- Use dropPSteps() to normalize before combining schedules
When it happens
Trigger: Calling schedule.advanced(next) where schedule has pSteps and next has steps (instruction steps). This happens when you first advance into p-code stepping (the '.' portion) and then try to append an instruction-level step.
Common situations: Building composite schedules from multiple user actions where the user first steps at p-code level then tries to step at instruction level. Merging schedule bookmarks that were recorded at different emulation granularities. Attempting to create a schedule that mixes instruction and p-code steps in an invalid order.
Related errors
- Cannot rewind a negative number
- The given prefix (%s) is not actually a prefix of this (%s).
- Thread must be given, e.g., 0:t1-3, since the last thread or
- Thread with key %d does not exist in given trace
- Cannot parse step: '
AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14).
Data as JSON: /api/errors/e2f1e194e98a640d.
Report an issue: GitHub.