RISC-V Trap Recovery: Advance mepc Only for the Instruction You Intend to Skip

A trap handler that always adds four to mepc can make a fault disappear while skipping the wrong instruction. The saved PC is part of a cause-specific recovery contract, not a generic “continue” cursor.

Decide first whether the interrupted operation should resume, be retried, be deliberately completed by emulation or terminate. Only then decide whether the saved PC must change and by how much.

Start with the trap’s meaning

The examined machine-level ISA 1.13 chapter specifies that mepc records the interrupted instruction or the instruction that encountered the exception. For ECALL and EBREAK, the saved exception PC points to that instruction itself, not the next instruction.

An ordinary asynchronous interrupt handler normally returns to the saved execution point without skipping an instruction. A handled environment call instead needs the execution environment's defined continuation. A fault repaired by changing a mapping may require retrying the same instruction.

Those cases cannot share an unconditional PC increment. Preserving the cause and saved PC before changing either makes an incorrect recovery decision diagnosable.

A compressed breakpoint is not four bytes long

The C extension 2.0 specification permits 16-bit and 32-bit instructions to be intermixed. Its C.EBREAK performs the breakpoint operation in a compressed encoding.

Suppose a deliberately handled compressed breakpoint starts at address 0x1000 and the following instruction starts at 0x1002. Advancing by four would return to 0x1004, potentially skipping that next instruction or landing in its middle. This is illustrative layout reasoning, not an executed debugger experiment.

A known standard ECALL is a 32-bit instruction, so its completed-call continuation can advance by four. That fact does not establish a universal size for every exception-producing instruction. If a handler supports emulation, its decoder must recognize the instruction formats it actually implements and reject unsupported cases rather than guessing a length.

Diagram contrasting trap continuation policies, a two-byte compressed breakpoint and the limits of mtval instruction information.
Original trap-continuation diagram. It illustrates architectural reasoning, not a reproduced fault or recovery test.

Interpret mtval according to the exception

The machine specification permits mtval to contain faulting instruction bits for an illegal-instruction exception, but this facility is optional. Zero can mean no instruction payload was supplied or that an illegal all-zero instruction was fetched. A zero value is therefore not a reliable instruction-length report.

For an instruction access or page fault involving a variable-length instruction, a nonzero mtval can identify the faulting portion while mepc still identifies the instruction's beginning. Treating the two addresses as interchangeable loses that distinction.

If software must fetch instruction bytes, use a platform-appropriate fault-aware path. A direct load from the saved address can itself fault, observe a different mapping or encounter modified code. Do not turn an incomplete diagnostic payload into an unchecked memory read inside the trap handler.

Keep recovery policy separate from decoding

Correctly determining an instruction's size does not mean it is safe to skip. An unperformed load, failed store or unsupported arithmetic operation may leave architectural or application state inconsistent with its consumer. Define the result or terminal policy before modifying the continuation address.

For a controlled qualification, use separate fixtures: an ordinary interrupt with unchanged continuation, a handled ECALL, a handled compressed breakpoint and an unsupported instruction that must not be silently skipped. Verify the exact resumed instruction and relevant register effects, not merely whether another log line appears.

Also test incomplete trap information and instruction-fetch failure under a recoverable laboratory setup. A decoder that handles only the happy-path bytes is not a complete recovery boundary.

No trap or debugger session was executed for this article. The acceptance condition is a cause-specific continuation with a supported instruction interpretation. Advancing the PC is the final consequence of that decision, not the default response to every trap.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *