Skip to content

Surviving Mars: Relaunched (3215050) #10169

Description

@aaalexandrov

Compatibility Report

  • Name of the game with compatibility issues: Surviving Mars: Relaunched
  • Steam AppID of the game: 3215050

System Information

  • GPU: AMD Custom GPU 0405 (RADV VANGOGH)
  • Video driver version: 35.0.99999.9999
  • Kernel version: OS: Windows 10 ver.10.0.19045 (as detected in our logs)
  • Proton version: 10.0

Note: I'm an employee at Haemimont Games, the game's developer

Symptoms

The game crashes with an exception inside XAudio2_9.dll

Call stack:
[Unhandled exception at 0x00006FFFFC5F8E29 (XAudio2_9.dll) in steamuser-Mars.exe-20260811-13.41.39-6a75e190.dmp: 0xC0000005: Access violation reading location 0x0000000000000004.]
XAudio2_9.dll!00006ffffc5f8e29() Unknown

XAudio2_9.dll!00006ffffc60b6c9() Unknown
[Inline Frame] Mars.exe!HSL::XAudioSound::DestroyVoice() Line 465 C++
Mars.exe!HSL::XAudioSound::Run() Line 1019 C++
Mars.exe!HSL::ThreadRun(void * p) Line 45 C++
Mars.exe!HSL::Debug::Try(void()(void ) guarded_func, void * pParam, void()() crash_func) Line 1558 C++
Mars.exe!HSL::ThreadRunProtected(void * p) Line 60 C++
[Inline Frame] Mars.exe!std::_Func_class::operator()() Line 1057 C++
Mars.exe!HSL::DefaultThreadProc(HSL::ThreadData * threadData) Line 235 C++
Mars.exe!thread_start<unsigned int (__cdecl
)(void *),1>(void * const parameter) Line 97 C++

Disassembly at the crash site:

00006FFFFC5F8DC0 push rbp
00006FFFFC5F8DC1 push r13
00006FFFFC5F8DC3 push r12
00006FFFFC5F8DC5 push rbx
00006FFFFC5F8DC6 sub rsp,48h
00006FFFFC5F8DCA lea rbp,[rsp+40h]
00006FFFFC5F8DCF mov r13,qword ptr [rcx]
00006FFFFC5F8DD2 mov rbx,r13
00006FFFFC5F8DD5 mov r12,rcx
00006FFFFC5F8DD8 test byte ptr [r13+0E0h],10h
00006FFFFC5F8DE0 jne 00006FFFFC5F8F34
00006FFFFC5F8DE6 mov rcx,qword ptr [rbx+30h]
00006FFFFC5F8DEA call 00006FFFFC607630
00006FFFFC5F8DEF mov rcx,qword ptr [rbx+18h]
00006FFFFC5F8DF3 test rcx,rcx
00006FFFFC5F8DF6 je 00006FFFFC5F8E69
00006FFFFC5F8DF8 nop dword ptr [rax+rax]
00006FFFFC5F8E00 mov rax,qword ptr [rcx]
00006FFFFC5F8E03 mov edx,dword ptr [rax+10h]
00006FFFFC5F8E06 test edx,edx
00006FFFFC5F8E08 je 00006FFFFC5F8E60
00006FFFFC5F8E0A mov r8,qword ptr [rax+14h]
00006FFFFC5F8E0E dec edx
00006FFFFC5F8E10 lea rdx,[rdx+rdx2]
00006FFFFC5F8E14 lea rax,[r8+4]
00006FFFFC5F8E18 lea rdx,[r8+rdx
4+10h]
00006FFFFC5F8E1D jmp 00006FFFFC5F8E29
00006FFFFC5F8E1F nop
00006FFFFC5F8E20 add rax,0Ch
00006FFFFC5F8E24 cmp rax,rdx
00006FFFFC5F8E27 je 00006FFFFC5F8E60
00006FFFFC5F8E29 cmp r12,qword ptr [rax] ; <-- Exception from here
00006FFFFC5F8E2C jne 00006FFFFC5F8E20
00006FFFFC5F8E2E mov rcx,qword ptr [rbx+30h]
00006FFFFC5F8E32 call 00006FFFFC607730
00006FFFFC5F8E37 mov edx,dword ptr [r13+0E0h]
00006FFFFC5F8E3E test dl,1
00006FFFFC5F8E41 jne 00006FFFFC5F8FA8
00006FFFFC5F8E47 and edx,10h
00006FFFFC5F8E4A mov eax,80004005h
00006FFFFC5F8E4F jne 00006FFFFC5F8F6A
00006FFFFC5F8E55 add rsp,48h
00006FFFFC5F8E59 pop rbx
00006FFFFC5F8E5A pop r12
00006FFFFC5F8E5C pop r13
00006FFFFC5F8E5E pop rbp
00006FFFFC5F8E5F ret

Reproduction

Multiple crash reports from users, a single on site reproduction on steam deck that produced a usable crash report that's cited above.
It seems to happen a lot in the wild but is not deterministic and hard to reproduce on site.

Investigation on our side

The crash is inside a call to IXAudio2SourceVoice::DestroyVoice()

According to Claude's analysis (which I have not checked personally but sounds plausible on the surface since we have not received any similar crash reports from Windows despite there being a lot more users), this is caused by a combination of our sound system aggressively calling into XAudio from multiple threads, and missing synchronization inside the Wine implementation. According to the MSDN documentation, windows serializes operations on the audio graph to execute on a separate processing thread, while Wine (inside DestroyVoice()) runs through every other voice's internal data without mutual exclusion. Claude narrowed that down to check_for_sends_to_voice() inside FAudioVoice_DestroyVoiceSafeEXT(). If we happen to call IXAudio2SourceVoice::SetOutputVoices({ .SendCount = 0, .pSends = nullptr }) on another thread on a voice currently being checked (which we do if that other voice is going to be destroyed soon too), this could lead check_for_sends_to_voice() to crash.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions