After adding FMOD to our Unity project we’ve been getting fairly frequent full program crashes due to segmentation faults. I haven’t been able to track down exactly how to reproduce the issue, but I have noticed that when it happens it’s during an assembly/domain reload, right after “Destroying editor system instance” based on the editor logs. There is a chance this is due to some extra scripting I’ve done, but I’m also getting some of the crashes when I revert to before I made any changes via version control. Any ideas on where to investigate would be very appreciated! More details below:
Versions:
Unity: 2020.3.8f1
FMOD Studio Unity Integration: 2.02.01
Apple Crash Report:
In particular, this is the section pointing me toward FMOD (in addition to this only happening after we added FMOD to the project)
Termination Signal: Segmentation fault: 11
Termination Reason: Namespace SIGNAL, Code 0xb
Terminating Process: Unity [47930]
VM Regions Near 0x7f8bc1f01858:
MALLOC_LARGE 7f8bc1eb4000-7f8bc1ec7000 [ 76K] rw-/rwx SM=PRV
-->
MALLOC_LARGE 7f8bc1f04000-7f8bc1f2f000 [ 172K] rw-/rwx SM=PRV
Thread 0 Crashed:: tid_307 Dispatch queue: com.apple.main-thread
0 libsystem_kernel.dylib 0x00007fff20481fde __kill + 10
1 libmonobdwgc-2.0.dylib 0x000000016bf9ed64 mono_chain_signal + 79
2 libmonobdwgc-2.0.dylib 0x000000016be8ddf5 mono_sigsegv_signal_handler + 443
3 libsystem_platform.dylib 0x00007fff204f4d7d _sigtramp + 29
4 ??? 000000000000000000 0 + 0
5 com.fmod.fmodstudioL 0x00000001f2c6061c 0x1f2a40000 + 2229788
6 com.fmod.fmodstudioL 0x00000001f2c62100 0x1f2a40000 + 2236672
7 com.fmod.fmodstudioL 0x00000001f2c6200f 0x1f2a40000 + 2236431
8 com.fmod.fmodstudioL 0x00000001f2c58453 FMOD::System::release() + 87
9 com.fmod.fmodstudioL 0x00000001f2a573e4 0x1f2a40000 + 95204
10 com.fmod.fmodstudioL 0x00000001f2a576c7 0x1f2a40000 + 95943
11 com.fmod.fmodstudioL 0x00000001f2b7e23b FMOD::Studio::System::release() + 417
12 ??? 0x000000022a823c5d 0 + 9303112797
Unity Editor Log:
Start importing Assets/Plugins/FMOD/src/Settings.cs using Guid(eef8d824ea7b63742966aaa0e94ac383) Importer(-1,00000000000000000000000000000000) -> (artifact id: '555e703788758b5cd0d56d513ec74310') in 0.021721 seconds
AssetDatabase: script compilation time: 0.092287s
- Starting script compilation
- Starting compile Library/ScriptAssemblies/FMODUnity.dll
Deleting stamp file at Library/ScriptAssemblies/BuiltinAssemblies.stamp
- Finished compile Library/ScriptAssemblies/FMODUnity.dll in 2.615378 seconds
- Skipping compile Library/ScriptAssemblies/FMODUnityEditor.dll because all references are unchanged
- Skipping compile Library/ScriptAssemblies/FMODUnityResonance.dll because all references are unchanged
- Skipping compile Library/ScriptAssemblies/FMODUnityResonanceEditor.dll because all references are unchanged
- Skipping compile Library/ScriptAssemblies/Assembly-CSharp.dll because all references are unchanged
- Skipping compile Library/ScriptAssemblies/Assembly-CSharp-Editor.dll because all references are unchanged
- Finished script compilation in 2.775349 seconds
Reloading assemblies after forced synchronous recompile.
Begin MonoManager ReloadAssembly
FMOD Studio: Destroying editor system instance
UnityEngine.StackTraceUtility:ExtractStackTrace () (at /Users/bokken/buildslave/unity/build/Runtime/Export/Scripting/StackTrace.cs:37)
UnityEngine.DebugLogHandler:LogFormat (UnityEngine.LogType,UnityEngine.Object,string,object[])
UnityEngine.Logger:Log (UnityEngine.LogType,object)
UnityEngine.Debug:Log (object)
FMODUnity.EditorUtils:DestroySystem () (at Assets/Plugins/FMOD/src/Editor/EditorUtils.cs:396)
FMODUnity.EditorUtils:HandleBeforeAssemblyReload () (at Assets/Plugins/FMOD/src/Editor/EditorUtils.cs:341)
UnityEditor.AssemblyReloadEvents:OnBeforeAssemblyReload () (at /Users/bokken/buildslave/unity/build/Editor/Mono/AssemblyReloadEvents.cs:15)
(Filename: Assets/Plugins/FMOD/src/Editor/EditorUtils.cs Line: 396)
Obtained 256 stack frames.
#0 0x000001f2c53cf1 in FMOD::SoundGroup::getUserData(void**)
#1 0x000001f2c6061c in FMOD::SystemI::createClientProfile()
#2 0x000001f2c62100 in FMOD::SystemI::setInternalCallback(int, FMOD_RESULT (*)(FMOD_SYSTEM*, unsigned int, void*, void*, void*), void*)
#3 0x000001f2c6200f in FMOD::SystemI::setInternalCallback(int, FMOD_RESULT (*)(FMOD_SYSTEM*, unsigned int, void*, void*, void*), void*)
#4 0x000001f2c58453 in FMOD::System::release()
#5 0x000001f2a573e4 in (null)
#6 0x000001f2a576c7 in (null)
#7 0x000001f2b7e23b in FMOD::Studio::System::release()
#8 0x0000022a823c5d in (wrapper managed-to-native) FMOD.Studio.System:FMOD_Studio_System_Release (intptr) {0x7f8bbdd1c698} + 0x5d (0x22a823c00 0x22a823ce5) [0x161042960 - Unity Child Domain]
#9 0x00000000000000 in (Unknown)
#10 0x00000000000000 in (Unknown)
#11 0x007f8bc60ad838 in (Unknown)
...
My changes:
Finally, the only changes I’ve made are in EditorUtils.cs
where I’ve hacked in the ability to play programmer sounds, very similar to what is done in the dialogue and audio tables example:
public static void PreviewEvent(EditorEventRef eventRef, Dictionary<string, float> previewParamValues, string key = "")
{
...
PreviewUpdateParameter(param.ID, previewParamValues[param.Name]);
}
}
if (!string.IsNullOrEmpty(key)) {
var dialogueCallback = new FMOD.Studio.EVENT_CALLBACK(DialogueEventCallback);
GCHandle stringHandle = GCHandle.Alloc(key, GCHandleType.Pinned);
previewEventInstance.setUserData(GCHandle.ToIntPtr(stringHandle));
previewEventInstance.setCallback(dialogueCallback);
}
CheckResult(previewEventInstance.start());
previewEventInstance.release();
previewState = PreviewState.Playing;
}
[AOT.MonoPInvokeCallback (typeof (FMOD.Studio.EVENT_CALLBACK))]
static FMOD.RESULT DialogueEventCallback(FMOD.Studio.EVENT_CALLBACK_TYPE type, IntPtr instancePtr, IntPtr parameterPtr)
{
// Retrieve the user data
IntPtr stringPtr;
FMOD.Studio.EventInstance instance = new FMOD.Studio.EventInstance(instancePtr);
instance.getUserData(out stringPtr);
// Get the string object
GCHandle stringHandle = GCHandle.FromIntPtr(stringPtr);
String key = stringHandle.Target as String;
switch (type)
{
case FMOD.Studio.EVENT_CALLBACK_TYPE.CREATE_PROGRAMMER_SOUND:
{
FMOD.MODE soundMode = FMOD.MODE.LOOP_NORMAL | FMOD.MODE.CREATECOMPRESSEDSAMPLE | FMOD.MODE.NONBLOCKING;
var parameter = (FMOD.Studio.PROGRAMMER_SOUND_PROPERTIES)Marshal.PtrToStructure(parameterPtr, typeof(FMOD.Studio.PROGRAMMER_SOUND_PROPERTIES));
FMOD.Studio.SOUND_INFO dialogueSoundInfo;
var keyResult = FMODUnity.RuntimeManager.StudioSystem.getSoundInfo(key, out dialogueSoundInfo);
if (keyResult != FMOD.RESULT.OK)
{
break;
}
FMOD.Sound dialogueSound;
var soundResult = FMODUnity.RuntimeManager.CoreSystem.createSound(dialogueSoundInfo.name_or_data, soundMode | dialogueSoundInfo.mode, ref dialogueSoundInfo.exinfo, out dialogueSound);
if (soundResult == FMOD.RESULT.OK)
{
parameter.sound = dialogueSound.handle;
parameter.subsoundIndex = dialogueSoundInfo.subsoundindex;
Marshal.StructureToPtr(parameter, parameterPtr, false);
}
}
break;
case FMOD.Studio.EVENT_CALLBACK_TYPE.DESTROY_PROGRAMMER_SOUND:
{
var parameter = (FMOD.Studio.PROGRAMMER_SOUND_PROPERTIES)Marshal.PtrToStructure(parameterPtr, typeof(FMOD.Studio.PROGRAMMER_SOUND_PROPERTIES));
var sound = new FMOD.Sound();
sound.handle = parameter.sound;
sound.release();
sound.clearHandle();
}
break;
case FMOD.Studio.EVENT_CALLBACK_TYPE.DESTROYED:
// Now the event has been destroyed, unpin the string memory so it can be garbage collected
stringHandle.Free();
break;
}
return FMOD.RESULT.OK;
}
Like I said, any suggestions of what to look for or investigate would be very appreciated!