Skip to content

Conversation

@TheusHen
Copy link

Description

Fixes emulator crashes during game load caused by memory corruption of the PPCContext::global_mutex pointer.

Problem

The emulator would crash with SIGSEGV in std::recursive_mutex::unlock() with an invalid this pointer (e.g., 0x1). Analysis of the callstack showed:

  • Crash occurred during GuestFunction::Callstd::recursive_mutex::unlock()
  • The PPCContext::global_mutex pointer was corrupted
  • Likely caused by guest code overwriting the context structure beyond the allocated stack red zone

Solution

Added defensive validation and restoration of the global_mutex pointer at three critical points:

  1. Processor::Execute: Validates before executing any function
  2. GuestFunction::Call: Validates before executing guest code
  3. BuiltinFunction::Call: Validates builtin arg0 pointer (global mutex reference)

When corruption is detected:

  • The pointer is restored to the valid global critical region mutex
  • An error is logged with the corrupted pointer value
  • Execution continues safely, preventing the crash

Testing

  • Tested with games that previously crashed on load
  • Corruption detection logging helps identify problematic guest functions for further investigation

#2297

@Triang3l
Copy link
Member

How does all of that happen at all? Fixing up after an error that has already happened, and state has already been corrupted in unpredictable ways, will just be hiding the problem, not solving it.

@TheusHen
Copy link
Author

I apologize for the approach taken in my previous commit. You're absolutely right, I was attempting to fix symptoms after corruption had already occurred rather than preventing the corruption in the first place.

The defensive checks I added merely detect that global_mutex has been corrupted and attempt to restore it, which doesn't solve the underlying problem and could mask more serious issues. The root cause is that guest code is somehow writing to the structure, corrupting the global_mutex pointer field.

I'll revert these changes and investigate the actual source of the memory corruption - likely related to stack overflow, red zone violations, or incorrect memory protection around the context structure. Thank you for the guidance.

Adds comprehensive validation of critical pointers in PPCContext and
BuiltinFunction to detect memory corruption before it causes crashes
in mutex operations.

Key improvements:
- Pre-execution validation of global_mutex pointer in Processor::Execute
- Post-execution validation to identify which function caused corruption
- Enhanced BuiltinFunction arg pointer validation with detailed errors
- Added validation in GuestFunction::Call before and after execution

These checks help identify the source of memory corruption (likely guest
code buffer overflows writing beyond VMX register arrays) and provide
detailed diagnostic information including function addresses, thread IDs,
and stack pointers.

The assertions ensure the emulator fails fast with clear error messages
rather than crashing with cryptic segfaults in std::recursive_mutex::unlock().
@Triang3l
Copy link
Member

Triang3l commented Nov 20, 2025

What places in which games is that crash reproducible in, by the way? It may be useful to be able to look at what actually happens there in the future.

@TheusHen
Copy link
Author

Well, at Forza Motorsport 4 in Linux

@Triang3l
Copy link
Member

Triang3l commented Nov 20, 2025

Linux is an interesting story. In the current form, the master branch of xenia-project/xenia is incapable of running games on Linux at all, but we have three pull requests implementing the System V ABI calling convention for guest<>host transitions:

On the Canary branch, though I'm not entirely sure, but it appears that #1339 is used.

Which implementation of the Linux calling convention are you testing Xenia with?

@TheusHen
Copy link
Author

I has used: #2228

@Triang3l Triang3l changed the title [CPU] Fix crash on game load caused by corrupted global_mutex pointer [Linux] [CPU] Fix crash on game load caused by corrupted global_mutex pointer Nov 20, 2025
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.

2 participants