NationalSecurityAgency/ghidra · error · IllegalArgumentException

Cannot step a negative number

Error message

Cannot step a negative number

What it means

Thrown by the AbstractStep constructor when tickCount < 0. A step represents a non-negative count of execution ticks (instruction or p-code steps) for a thread key; a negative count is meaningless. All concrete step types inherit this guard.

Source

Thrown at Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/model/time/schedule/AbstractStep.java:29

 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package ghidra.trace.model.time.schedule;

import java.util.List;

import ghidra.program.model.lang.Language;
import ghidra.trace.model.time.schedule.TraceSchedule.TimeRadix;

public abstract class AbstractStep implements Step {
	protected final long threadKey;
	protected long tickCount;

	protected AbstractStep(long threadKey, long tickCount) {
		if (tickCount < 0) {
			throw new IllegalArgumentException("Cannot step a negative number");
		}
		this.threadKey = threadKey;
		this.tickCount = tickCount;
	}

	/**
	 * Return the step portion of {@link #toString()}
	 * 
	 * @param radix the radix
	 * @return the string
	 */
	protected abstract String toStringStepPart(TimeRadix radix);

	@Override
	public String toString() {
		return toString(TimeRadix.DEFAULT);
	}

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Pass a non-negative tick count; clamp computed counts with Math.max(0, n).
  2. When splitting/merging schedules, recompute counts from absolute positions rather than differences that can go negative.
  3. Use TraceSchedule's higher-level combine/rewind APIs which keep counts non-negative.

Example fix

// before
Step s = new TickStep(threadKey, remaining /* -3 */);

// after
Step s = new TickStep(threadKey, Math.max(0, remaining));
Defensive patterns

Strategy: validation

Validate before calling

long ticks = Math.max(0, computedTicks);
Step s = new TickStep(threadKey, ticks);

Type guard

static boolean validTickCount(long t) { return t >= 0; }

Prevention

When it happens

Trigger: Constructing a step (e.g. TickStep/ExecutorStep) via its constructor or parse path with a negative tick count; arithmetic that subtracts past zero before building a step.

Common situations: Schedule parsing/computation that underflows; rewinding and re-deriving a step count without clamping; tests building steps with arbitrary ints.

Related errors


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