Commit Graph
104 Commits
Author SHA1 Message Date
Henrik RydgårdandClaude Opus 5 75ff0d406c Rename Memory::Lock() to Core_LockAgainstShutdown(), move it to Core
It stopped being about memory when CPU_Shutdown started holding it across the
whole teardown - it's what keeps kernel objects, the symbol map and the memory
map from being freed while another thread reads them. The old name invited the
reading that it locks memory *access*, which it has never done.

Memory::Reinit() now holds it across both halves rather than relying on
Memory::Shutdown()'s own acquire: between Shutdown() and Init() there is no
memory map at all, and a reader could slip into that gap.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GZq8ZtJmFY7bkX5FVkr3P9
2026-08-17 13:11:16 +02:00
Henrik RydgårdandClaude Opus 5 81511e7a08 Fix deadlock between the Win32 debugger's paint handlers and the CPU thread
Reported hang: the CPU thread held g_frameMutex (NativeFrame) and blocked on
g_shutdownLock inside a queued memory.read, while the GUI thread held
g_shutdownLock (CtrlMemView::onPaint) and blocked on g_frameMutex. Textbook
ABBA.

The CPU thread's order is structural - NativeFrame wraps everything below it in
g_frameMutex, and both Core_ProcessCPUQueue() and runImDebugger() ->
DisassembleRange() lock memory from under there - so the GUI side is the one
that has to match. Swaps the three handlers that had it backwards
(CtrlMemView::onPaint, CtrlDisAsmView::onPaint, CtrlStackTraceView::
loadStackTrace) to take g_frameMutex first. They already took both locks, so
this is ordering only, and g_shutdownLock is recursive so nesting is fine.

Also drops the Memory::MemoryInitedLock from the WebSocket LockMemory(), which
is what made the CPU thread want that lock in the first place. It was guarding
against another thread tearing down the memory system, but that doesn't happen:
Memory::Shutdown() is only reached via CPU_Shutdown() <- PSP_Shutdown(), whose
callers all run on the CPU thread, and Memory::Reinit() runs from
Memory::DoState() on savestate load, likewise. WebSocket.cpp additionally holds
lifecycleLock across the whole handler and takes it on STOPPING.

Note this second part isn't sufficient on its own - ImMemView's copy-disassembly
path also locks memory from inside the frame span - which is why the ordering
fix is the real one.

Not removing Memory::Lock() from the Win32 paint handlers: teardown isn't fully
inside the g_frameMutex span yet. EmuScreen::render()'s PSP_Shutdown() is, but
the ones in EmuScreen::sendMessage() (game reset, loading a new game) run from
g_screenManager->sendMessage(), above where NativeFrame takes the guard. Closing
that is the prerequisite, and is left for later.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GZq8ZtJmFY7bkX5FVkr3P9
2026-08-17 00:29:44 +02:00
Henrik Rydgård d8edeb7649 Interpreter: Add correct alignment checks to loads/stores, cleanup 2026-08-11 10:28:48 +02:00
Henrik RydgårdandClaude Sonnet 5 f72709feb0 Legacy Win32 debugger: fix the painting problem with a frame-scoped mutex
Debugger windows (register list, disassembly view, memory view, breakpoint/
thread/module/stack lists, watch list) read CPU-thread-owned state directly
from the GUI thread's WM_PAINT/list-fill handlers, racing against the CPU
thread. Routing every read through Core_RunOnCPUThread would be too slow for
something invoked continuously on paint/list-refresh.

Add g_frameMutex (Core.h/Core.cpp), held by NativeFrame() only across the
span where it actually touches that state (running the CPU, processing
breakpoints, running the ImGui debugger) - not across input handling or the
present/frame-pacing waits. Debugger windows now hold the same mutex while
reading, giving synchronized reads without the round-trip cost of queuing
to the CPU thread.

CtrlRegisterList::onPaint() goes back to always reading live values (now
safe under the lock) and grays them out by color alone while the core is
running, rather than the earlier snapshot-caching approach.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Hqm11k99viLfbJm2MkH4BH
2026-08-08 17:22:12 +02:00
Henrik RydgårdandClaude Sonnet 5 25c3c90c94 Legacy Win32 debugger: route mutations through the CPU thread
The Win32 debugger dialogs mutate CPU-thread-owned state (breakpoints,
symbol map, registers, memory, kernel threads) directly from the GUI
thread with no synchronization, same problem the WebSocket debugger had.
Route all of these through Core_RunOnCPUThread instead, following the
same pattern used there.

Also drops two forced-pause (Core_Break/Core_WaitInactive/Core_Resume)
dances in CtrlMemView::onChar and DumpMemoryWindow's dump handler, now
unnecessary since Core_RunOnCPUThread works whether the CPU is running
or already stepping.

Modal dialogs (MessageBox, InputBox_GetString, BreakpointWindow::exec,
etc.) are kept outside any queued callback so they never block the CPU
thread on user input. Pure reads/painting (disassembly formatting,
search, list reloads, onPaint) are intentionally left as-is for now.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Hqm11k99viLfbJm2MkH4BH
2026-08-08 17:22:12 +02:00
Henrik Rydgård 330a638281 Add ability to copy function hash from the disassembly view
See #4179
2026-02-09 19:26:43 +01:00
Henrik Rydgård 5f7a937466 Rename ValidSize to ClampValidSizeAt 2025-12-30 20:31:07 +01:00
Henrik Rydgård 09e067c6e1 Revert "Get rid of remains of support for non-square screen DPIs"
This reverts commit f206ed95eb.
2025-05-21 21:41:50 +02:00
Henrik Rydgård f206ed95eb Get rid of remains of support for non-square screen DPIs 2025-02-20 11:14:26 -06:00
Henrik Rydgård 31cf5771f4 Turn the break reason into an enum, fix some minor issues 2025-02-19 16:01:11 -06:00
Henrik Rydgård 3e198c53b2 More include cleanup 2024-12-18 13:57:26 +01:00
Henrik Rydgård a8744f5992 Disable the native debugger when RetroAchievements hardcore mode is enabled 2024-11-10 19:19:03 +01:00
Henrik Rydgård d3e9398cb3 Split Core_EnableStepping into Core_Break and Core_Resume 2024-11-03 17:53:42 +01:00
Henrik Rydgård 126d88ecfc Back out clearly inconsequential/useless .reserve() calls 2023-12-29 08:27:56 +01:00
Henrik Rydgård 6945deec01 Replace a LOT of sprintf with snprintf, and a few strcpy with truncate_cpy 2023-04-28 21:04:05 +02:00
Henrik Rydgård 178fe27263 Merge pull request #17269 from unknownbrackets/debugger-minor
Debugger: Avoid unaligned reads in expressions
2023-04-12 10:38:08 +02:00
Unknown W. Brackets 9cebfc31b3 Debugger: Avoid unaligned reads in expressions.
Potentially, a watch or break condition could crash if it was unaligned
between mirrors.  This might happen if it's not the condition you wanted,
especially.  Play it safe.
2023-04-12 01:14:30 -07:00
Nemoumbra 5bf22c15d0 sceKernelPrintf improvement, QOL adjustments 2023-04-11 15:47:50 +03:00
Henrik Rydgård 3c9e968ca0 Merge pull request #17206 from unknownbrackets/debugger
Debugger: Fix memory viewer, inverted check
2023-03-29 08:07:39 +02:00
Unknown W. Brackets a4d13d5f75 Debugger: Fix memory viewer, inverted check. 2023-03-28 22:52:01 -07:00
Nemoumbra 4a54409f09 Added new option "Copy Float (32 bit)" to Windows Debugger UI 2023-03-28 13:18:20 +03:00
Henrik Rydgård 8b431b39ba Wrap the display globals in a struct (#16998)
* Wrap the display globals in a struct

Makes it easier to search/replace these, for future refactorings.

* Some renaming

* Qt buildfix, also fix the Qt build on Mac (got broken with battery changes)

* Attempt at buildfixing ios

* UWP buildfix
2023-02-25 13:09:44 +01:00
Unknown W. Brackets 88489bf4cc Debugger: Fix out of bounds read for unsized copy. 2023-01-04 21:42:46 -08:00
Unknown W. Brackets 7c099dc764 Debugger: Allow copy of byte range from memview. 2023-01-01 23:02:12 -08:00
Unknown W. Brackets bba748d627 Debugger: Handle memview select right click better.
Shouldn't reset if you click inside.  Also should basically ignore
modifiers, that's how it normally behaves.
2023-01-01 22:49:04 -08:00
Unknown W. Brackets a7101b128f Debugger: Allow memview select with keyboard. 2023-01-01 22:37:53 -08:00
Unknown W. Brackets f66818ba80 Debugger: Allow selecting a range in memory view. 2023-01-01 22:28:29 -08:00
Unknown W. Brackets f8064c6763 Debugger: Cleanup memview members.
Was fairly inconsistent.  This code has not changed a lot in a long time,
so let's just do a single cleanup pass before some changes.
2023-01-01 21:47:39 -08:00
lainon 3cdf72b68b Better readability and optimization insertion into container by replacing 'insert' -> 'emplace', 'push_back' -> 'emplace_back' 2022-09-30 12:35:28 +03:00
lainon b304551747 Code readability, vec reserve() and remove excess c_str() 2022-09-30 12:31:32 +03:00
lainon fec708489a Correct cleaning string and remove unused vars 2022-09-30 12:26:30 +03:00
Unknown W. Brackets 1233d1d376 Reporting: Disable when debugger methods used.
This won't catch all means of hacking memory, but will catch some.
Trying to reduce noise in reporting from debugging.
2022-07-30 18:21:32 -07:00
Henrik Rydgård d3d601dced Windows fixes 2022-07-24 13:58:20 +02:00
Unknown W. Brackets d583720f2b Debugger: Search scratchpad/ram/vram consistently. 2022-02-10 20:39:29 -08:00
Unknown W. Brackets de1a6a93d8 Debugger: Debounce redraws using timers. 2021-12-12 10:22:21 -08:00
Unknown W. Brackets 2bd13c5d9d Debugger: Track reason for entering stepping. 2021-10-23 16:56:15 -07:00
Unknown W. Brackets 39d3b4d933 Debugger: Centralize context menu handling.
This deduplicates a bit, but more importantly keeps all the IDs together.
2021-10-07 19:48:13 -07:00
Unknown W. Brackets 58238abef5 Debugger: Fix submenu offsets from removing unused.
The wrong menus were showing in several places, especially the GE
debugger.
2021-10-07 07:04:33 -07:00
Unknown W. Brackets d8198ae3c2 Debugger: Implement goto in disasm for memory view.
This had been in the menu for a while, but not working.
2021-10-03 06:53:58 -07:00
Unknown W. Brackets 2932a9995f Debugger: Prompt with previous search string.
When searching, fill the text box with the previous search by default.
Convenient when you want to edit it.
2021-04-21 19:47:18 -07:00
Unknown W. Brackets 4285485157 Debugger: Add menu to jump to begin/end of alloc.
Helpful when viewing memory.  Should add a shortcut too...
2021-04-03 16:03:21 -07:00
Unknown W. Brackets de72190344 Debugger: Update status on scroll down.
And include the start and end of the range.
2021-02-15 15:01:23 -08:00
Unknown W. Brackets a4ed6eb167 Debugger: Fix memory lookup in mirrors/uncached.
Oops, was crashing before since it's outside the index.
2021-02-15 15:01:23 -08:00
Unknown W. Brackets d48bb7e105 Debugger: Show memory tag info in status bar. 2021-02-15 15:01:23 -08:00
Unknown W. Brackets b1a2090e67 Debugger: Extend tag background on select too. 2021-02-15 15:01:23 -08:00
Unknown W. Brackets c044e6f7e4 Debugger: Highlight memory ranges in memory view. 2021-02-15 15:01:23 -08:00
Unknown W. Brackets d80655287b Debugger: Reorganize memory view painting.
This also grabs tag info, but doesn't display it yet.
2021-02-15 15:01:23 -08:00
Unknown W. Brackets 616850663c Debugger: Add initial UI for mem info type.
Does not visualize yet, just implements the selection interface.
2021-02-15 15:01:23 -08:00
Unknown W. Brackets 616f5ddc5a Debugger: Correct search by empty string. 2021-02-15 15:01:23 -08:00
Henrik Rydgård b7edf75437 Move Display.cpp/h to Common. 2020-10-04 11:42:16 +02:00