Skip to content

Fix SMS/GG debugger step-back non-determinism bug#16

Open
CharlesVanEeckhout wants to merge 1 commit intonesdev-org:masterfrom
CharlesVanEeckhout:gg-stepback
Open

Fix SMS/GG debugger step-back non-determinism bug#16
CharlesVanEeckhout wants to merge 1 commit intonesdev-org:masterfrom
CharlesVanEeckhout:gg-stepback

Conversation

@CharlesVanEeckhout
Copy link
Copy Markdown

i had originally found this bug on mesen 2.1.1 on 2025-10-20
heres what i had written back then on the snesdev discord:

i have found a non-determinism bug with the step-back function of the mesen debugger
i have coded a homebrew rom to isolate and demonstrate this bug
stepback.gg.zip

steps to reproduce:

1. place breakpoint at game gear memory 0x00B2 (instruction should be ld b, a)
2. continue execution until the breakpoint. notice that A register is $55
3. continue execution past the breakpoint. this $55 is used to make the background dark gray.
4. reset the rom and run rom until the breakpoint
5. this time, use the step-back function (shift+f10) until pc is 0x00a9 (this should be the first of eight nop)
6. continue execution until the breakpoint again. notice that A register is now $AA
7. continue execution past the breakpoint. this $AA is used to make the background light gray.

this is a bug because the value of A register at step 2 and the value of A register at step 6 should be the same value

root cause for the bug:

in Core/SMS/SmsVdp.cpp, some calls to SmsVdp::ProcessVramAccess only occur when _memAccess[cyc] == SmsVdpMemAccess::None
going forward normally, the _memAccess[cyc] would be SmsVdpMemAccess::None, and then inside SmsVdp::ProcessVramAccess, it would be set to SmsVdpMemAccess::CpuSlot, and would eventually get cleared when the scanline ends
but if instead of letting the scanline end, i step-back to before the SmsVdp::ProcessVramAccess call, since _memAccess is not serialized, _memAccess[cyc] remains SmsVdpMemAccess::CpuSlot instead of returning to SmsVdpMemAccess::None as would be expected
this makes the call to SmsVdp::ProcessVramAccess fail to occur as it had the first time around, because _memAccess[cyc] == SmsVdpMemAccess::None is no longer true
because the vram access now fails to occur, stale values remain in the _state.VramBuffer for longer than they should (this is the $AA in my example)

my solution:

i serialized the _memAccess array
this way, stepping-back restores the previous values of _memAccess correctly, thus allowing all SmsVdp::ProcessVramAccess calls that depend on _memAccess to remain consistent, whether or not step-back is used

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant