Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Window focus regain causes debugger to step ahead #20004

Closed
3 of 5 tasks
banyaszvonat opened this issue Feb 19, 2025 · 4 comments
Closed
3 of 5 tasks

Window focus regain causes debugger to step ahead #20004

banyaszvonat opened this issue Feb 19, 2025 · 4 comments
Labels
Milestone

Comments

@banyaszvonat
Copy link

banyaszvonat commented Feb 19, 2025

Game or games this happens in

ULES-00999 - Disgaea Afternoon of Darkness

What area of the game / PPSSPP

The issue happens when using the builtin debugger. The rough steps to reproduce:

  • Ensure "System -> Pause when not focused" is on in the settings
  • Load the game
  • Open up the disassembler window
  • Set a read/write breakpoint with the "Break" property enabled
  • Once the breakpoint is hit, switch windows (either to the debugger window, or a different window altogether)
  • Focus the emulator window again
  • Current instruction indicator will have moved to the next breakpoint, or possibly, looped around altogether to the next iteration of the gameloop.

The issue is easier to see if there are multiple read/write breakpoints.

Since I'm not a 100% certain it happens every time, here's are specific steps for the European version of Disgaea: Afternoon of Darkness:

  • Ensure "System -> Pause when not focused" is on in the settings
  • Load up the first level (Skipping the cutscene)
  • Set read/write breakpoints on 0x08980E3E and 0x08980E3F, with the Break property enabled
  • Ensure execution is stopped at 0x08836AF4
  • Optionally, set an execute breakpoint at 0x08836AF8
  • If the emulator window is out of focus, make it the active window
  • If the emulator window is already in focus, switch to a different window, then back
  • Observe in debugger window that pc/the current instruction indicator has moved to 0x08836B0C if the above execute breakpoint was not set, or to 0x08836AF8 if it was set.

The issue does not happen if emulation is explicitly paused by bringing up the PPSSPP menu. The issue also disappears without the need for pausing if "Pause when not focused" is disabled in the settings.

Before window regains focus:
Image

After window regains focus:
Image

Since I don't remember if and what data I altered in it, the savedata I'm using is probably not suitable for upload. But if needed, I'll produce a "clean" savefile.

What should happen

If the game is stopped at a breakpoint, execution should not continue when the window regains focus, regardless of the value of "Pause when not focused".

Logs

No response

Platform

Windows

Mobile device model or graphics card (GPU)

NVIDIA Geforce GTX 960M

PPSSPP version affected

v1.8.1-g0f50225 (v1.8.1 Git release)

Last working version

No response

Graphics backend (3D API)

Direct3D 11

Checklist

  • Test in the latest git build in case it's already fixed.
  • Search for other reports of the same issue.
  • Try resetting settings or older versions and include if the issue is related.
  • Try without any cheats and without loading any save states.
  • Include logs or screenshots of issue.
@hrydgard hrydgard added this to the v1.19.0 milestone Feb 19, 2025
@hrydgard
Copy link
Owner

hrydgard commented Feb 19, 2025

Hm, yeah, I can see how this would happen... Re-using the debugger break feature to implement the pause feature caused this, although adding more different pause features might not be a better idea, just more states to debug.

It should be possible to just check the break reason and not resume if the break wasn't caused by switching focus.

EDIT: Actually we already seem to have this check.. weird:

Core_BreakReason() == "ui.lost_focus" in MainWindow.cpp

Ah, I think there are a bunch of cases where we just leave that value around...

@banyaszvonat
Copy link
Author

banyaszvonat commented Feb 19, 2025

Re-using the debugger break feature to implement the pause feature caused this

This is what I suspected from the behavior, but I wasn't familiar enough with the code to find a root cause. Thanks for the pointers!

Core_BreakReason() == "ui.lost_focus" in MainWindow.cpp

After a quick look, it seems like on focus loss, stemming from the implementation as a finite state machine, ultimately the g_cpuStepCommand.reason gets overwritten no matter what, so there is no way to tell whether it also had been stopped for other reasons prior to focus loss. EDIT: misread the code, nevermind.

If you don't mind a bit of speculation: my mental model (that turned out wrong) expected a two-tier system, where debugger-based breaks are a different tier than pauses originating from the UI. It does not look like this behavior can be conveniently be represented with a FSM. Might want to consider a pushdown automaton (e.g.: https://gameprogrammingpatterns.com/state.html ) to represent stepping state. I think it might simplify things and prevent similar bugs in the future.

I can't promise I can make such a change in an unfamiliar codebase without breaking other things, but maybe I'll experiment with it.

@banyaszvonat
Copy link
Author

banyaszvonat commented Feb 19, 2025

Update: seems like the reason I encountered this bug despite the check was because the fix ( #19914 ) wasn't in the latest release yet. And I didn't realize the "latest git build" referred to dev builds. Sorry!

@hrydgard
Copy link
Owner

Oh, okay. Closing then, but your report also caused me to clean up some of this :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants