Commit Graph
62 Commits
Author SHA1 Message Date
Henrik RydgårdandClaude Sonnet 5 29a38af37e Per-module symbol save/load, module identity via crc, GetModuleIndex fix
SymbolMap:
- Fix GetModuleIndex(): it only checked the end of an active module's range
  (via activeModuleEnds.upper_bound), never the start, so an address sitting
  in the gap before a module was silently misattributed to it. Added
  GetModuleIndexByName() as a companion lookup.
- AddModule() gains an optional crc param, stored per ModuleEntry. Reactivating
  a module by name now also requires the crc to agree when both sides know it,
  so two unrelated binaries that happen to share a name no longer get merged
  into one symbol table (addresses the old TODO at the top of SymbolMap.h).
- AddLabel()/AddFunction() gain an updateName param (default false, preserving
  existing "first writer wins" behavior) so a trusted source - like a loaded
  symbol file - can be allowed to overwrite a name that a lower-confidence
  automatic pass already assigned.
- New SaveModuleSymbols()/LoadModuleSymbols()/GetModuleSymbolsPath(): save or
  restore one module's functions/data/labels to/from a small human-editable
  text file, addressed relative to the module (so the file stays valid however
  the module ends up positioned on a later run). Keyed by
  PSP/SYSTEM/SYMBOLS/<moduleName>_<crc>.ppsym - deliberately by module+crc
  rather than by game, so it's shared by every game/homebrew that loads the
  exact same module. A "# game <id> <title>" comment records who last saved
  it, informational only.

WebSocket debugger: hle.module.saveSymbols/loadSymbols expose the above.

sceKernelModule.cpp: auto-load a module's saved symbols right after it's
registered with the symbol map (both the real ELF-load path and the
savestate-load path), and auto-save on unload (before UnloadModule(), while
its symbols are still active) - gated behind the new bAutoSaveLoadSymbols
config setting (default off), with a matching Developer Tools checkbox and
a --auto-save-load-symbols command-line override for headless use.

Includes some in-progress cleanup already staged: DescribeAddress now calls
g_symbolMap->GetDescription() directly instead of through the now-removed
MIPSDebugInterface::getDescription() wrapper.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GZq8ZtJmFY7bkX5FVkr3P9
2026-08-17 16:01:23 +02:00
Henrik Rydgård f5bd302694 Improve DescribeAddress, show the description of the currently selected line in disassembly 2026-08-14 14:38:33 +02:00
Henrik Rydgård e9a3449ede More MIPSState * plumbing (manual) 2026-08-12 14:02:19 +02:00
Henrik Rydgård 9afab39bc8 MemBlockInfo: fix double-lock deadlock in FindWriteTagByFlag (previous commit)
FindWriteTagByFlag(flush=false) is only called from
FormatMemWriteTagAtNoFlush(), which is itself only called from within
FlushPendingMemInfo() - which already holds pendingReadMutex for its
entire body. The previous commit added an unconditional lock of that
same (non-recursive) mutex here, so any path that reaches a memory
write's tag formatting while a flush is in progress double-locks it
and hangs/crashes.

Repro: PPSSPPHeadless --graphics=software on
pspautotests/tests/gpu/clipping/homogeneous.prx reliably hit this.

Only take the lock when flush=true (i.e. when we're not already
guaranteed to be called from inside FlushPendingMemInfo's locked
section), using a defer_lock so the two call sites stay consistent.
Verified fixed: 4/4 clean runs of the repro above, plus the full
UnitTest suite (49/49) still passes.
2026-08-12 09:43:16 +02:00
Henrik Rydgård 527c50d32e MemBlockInfo: fix unsynchronized access to the slab maps from readers
The background flush thread calls FlushPendingMemInfo() at any time
while the emulator runs, holding pendingReadMutex for its whole body
while calling MemSlabMap::Mark() - which does new/delete and relinks
the intrusive Slab linked list via Split()/Merge().

FindMemInfo()/FindMemInfoByFlag()/FindWriteTagByFlag() only acquired
that lock indirectly and conditionally, inside FlushPendingMemInfo()
itself when the requested range happened to overlap pending data - the
actual .Find()/.FastFindWriteTag() traversal that followed ran
completely unsynchronized against the background thread's Mark() calls
on the same maps. This is a genuine use-after-free: a reader could
dereference a Slab* the flush thread just deleted, or race on the
shared lastFind_ pointer both sides read and write. Since a Slab's tag
is copied into the debugger's/WebSocket API's response, this could
also leak stale/freed heap bytes back to a caller. MemBlockInfoDoState
had the same gap around allocMap/suballocMap/writeMap/textureMap's
.DoState() calls.

Hold pendingReadMutex for the duration of these calls too, matching
the comment already on FlushPendingMemInfo ("This lock prevents us
from another thread reading while we're busy flushing") which wasn't
actually honored by the reader side.
2026-08-12 09:42:32 +02:00
Henrik Rydgård a44c2c0bde Replace System_SendDebugOutput with a registered callback
I normally try to avoid registrations when not needed, but in this case
only headless uses this, so it's motivated.
2026-08-11 22:36:47 +02:00
Henrik Rydgård d87a98c4a8 Avoid wasting CPU on counting characters in the memblock management
Unittest and a bugfix by claude.
2026-08-07 08:56:41 +02:00
Henrik Rydgård d6ebfed432 Fix some bugs and warnings from a pass of static analysis 2026-01-29 17:41:54 +01:00
Henrik Rydgård 5751e202a5 Remove redundant .c_str() 2025-08-31 13:37:43 +02:00
Henrik Rydgård c91169e702 Restore removed <algorithm> includes.
Turns out these were needed after all. For some reason, on Windows and
Mac, <algorithm> gets auto-included by something else so I don't notice
when it's missing, and MSVC's include dependency tracker doesn't see it
either.
2024-12-19 09:53:07 +01:00
Henrik Rydgård 45cf6d423e Buildfixes 2024-12-18 13:57:29 +01:00
Henrik Rydgård 3e198c53b2 More include cleanup 2024-12-18 13:57:26 +01:00
Henrik Rydgård 7992ff4627 Make CBreakpoints an object 2024-11-25 00:22:53 +01:00
Henrik Rydgård fd9daf7594 Fix some minor issues found by --sanitize. Add --sanitizeub.
Unfortunately the ub (undefined behavior) sanitizer has some bugs, it doesn't
understand pointers to member functions, so can't use it in-game (due to the
vertex decoder).

Thanks Nemoumbra for the reminder.
2024-07-22 11:37:18 +02:00
Henrik Rydgård 01c2ffd5f5 Add a missing thread name 2024-01-29 13:52:38 +01:00
Henrik Rydgård 6aaf9b0fc8 Remove unmotivated check
See comments on #18543

I don't see how we ever ran out of bounds there.
2023-12-29 08:54:58 +01:00
Henrik Rydgård 2f1389233e MemBlockInfo: Fix potential out-of-bounds in the slab map, reported by Nemoumbra 2023-12-13 21:53:16 +01:00
Unknown W. Brackets 0668a60406 Debugger: Improve savestate load performance. 2023-09-30 15:53:41 -07:00
Unknown W. Brackets fc133f4994 Debugger: Use a thread to flush meminfo. 2023-09-24 20:03:27 -07:00
Unknown W. Brackets b0da32f41f Debugger: Defer copy src tag lookups. 2023-09-24 19:07:45 -07:00
Unknown W. Brackets a416478780 Debugger: Skip tag copy on READ notify. 2023-09-24 19:07:45 -07:00
Unknown W. Brackets 810d8c0890 Debugger: Use dedicated func to notify mem copy. 2023-09-24 19:07:36 -07:00
Unknown W. Brackets d5c91fa02c Debugger: Reduce cost of small copy tracking.
This uses another 400KB RAM and does a bit more writing, but makes lookups
faster.
2023-08-31 00:17:30 -07:00
Unknown W. Brackets 3d61f97b81 Debugger: Fix allocs+writes collapsing together. 2023-05-06 13:39:31 -07:00
Henrik Rydgård dc74778dea Do the last ones too 2023-02-09 10:27:29 +01:00
Unknown W. Brackets 3938c0a3af Debugger: Combine mem info on duplicates.
Gran Turismo does some churn on texture sizes, we can combine them and
reduce the speed hit even when detailed.
2022-11-18 23:11:11 -08:00
Unknown W. Brackets 58a4376998 GPU: Normalize framebuf addresses.
In VRAM, always store without mirror.  In RAM, always store without
cache/kernel bits.
2022-10-02 21:28:53 -07:00
Henrik Rydgård ecb84987ef Remove allocation from the heaviest MemBlockInfo path (BlockTransfer). Required some refactoring. 2022-09-01 11:59:35 +02:00
Unknown W. Brackets 7f07b4154a Debugger: Keep separate tag dirty for RAM.
VRAM and RAM can often be separately dirty, so keeping two ranges helps
reduce flushing, and flushing things together is more efficient.
2022-03-20 13:24:42 -07:00
Unknown W. Brackets 7eafbb54bd Debugger: Fast path write tag lookup. 2022-03-20 13:19:13 -07:00
Unknown W. Brackets 6945151384 Debugger: Improve tag on copies.
MemInit shows up sometimes when the allocation would be more useful.
2022-03-20 12:05:31 -07:00
Unknown W. Brackets 80e054b797 Debugger: Avoid write tag lookup on small alloc. 2022-02-06 09:28:48 -08:00
Unknown W. Brackets 664d18cc9d Debugger: Encourage better meminfo accounting.
This makes MSVC generate a tighter loop and inline.
2022-01-30 08:03:54 -08:00
Unknown W. Brackets 0f2fc00f1b Debugger: Avoid flushing meminfo on write lookup.
Small improvement on frequent block transfers, etc.
2022-01-15 19:43:16 -08:00
Unknown W. Brackets 9155cd7491 Debugger: Reduce meminfo block check hazard.
If a debugger (i.e. the memory view) checks for memory block info while a
save state is being loaded, it can crash.  This was already rare, but this
change makes it significantly rarer.

Of course, it's still possible without a mutex, but I'm wanting to avoid
slowing down the lookups as they are used at runtime within emulation.
2021-12-04 14:51:02 -08:00
Unknown W. Brackets 5904900d37 Debugger: Add APIs to set/list/search mem tags. 2021-04-06 12:09:39 -07:00
Unknown W. Brackets 7a1398844a Debugger: Add simple API to control tagging detail.
In case a client requires it.
2021-04-04 20:23:51 -07:00
Unknown W. Brackets ee749804fc Debugger: Note GPU block transfer src as well. 2021-04-03 18:11:44 -07:00
Unknown W. Brackets aa89ed5111 Debugger: Include source tag in memcpys. 2021-04-03 18:11:44 -07:00
Unknown W. Brackets c88757b3e7 Debugger: Make memory tags longer.
Need more space for better information.
2021-04-03 16:04:07 -07:00
Henrik Rydgård ecad18a4f0 Merge pull request #14293 from unknownbrackets/debugger
Debugger: Ignore small memory info by default
2021-03-16 08:59:35 +01:00
Unknown W. Brackets b93e02ad73 Debugger: Ignore small memory info by default.
The ini can be updated to enable higher resolution data.  Allocations are
always at least 0x100, so this is still pretty useful.
2021-03-14 15:10:35 -07:00
Henrik Rydgård 63a94ceebb Fix performance regression from failing to optimize the new mem tracker.. 2021-03-14 21:27:20 +01:00
Unknown W. Brackets 8d6c1c6d9b Debugger: Fix save state compat for slab info. 2021-03-13 10:03:02 -08:00
Henrik Rydgård 0780976fe7 Remove static assert on struct size, we don't really care that much.
Caused problems on 32-bit.
2021-03-13 17:36:10 +01:00
Henrik Rydgård 3c211a6b99 Buildfix 2021-03-13 17:28:47 +01:00
Henrik Rydgård 797cc41a1c Remove std::string from memblockinfo 2021-03-13 17:12:30 +01:00
Unknown W. Brackets ee71ef961f Debugger: Keep char *s for memchecks. 2021-02-20 16:16:43 -08:00
Unknown W. Brackets 07de2e5401 Debugger: Prevent thread errors on mem alloc info. 2021-02-15 15:01:23 -08:00
Unknown W. Brackets 8d58bbb634 Debugger: Correct merging fragmented blocks.
Oops, wasn't clearing them so was eventually maxing out fragmentation.
2021-02-15 15:01:23 -08:00