rlabrecque / Steamworks.NET

Steamworks wrapper for Unity / C#
http://steamworks.github.io
MIT License
2.65k stars 350 forks source link

Unity hard crash on SteamNetworkingUtils.SetConfigValue() since updating to latest #475

Open jsmars opened 2 years ago

jsmars commented 2 years ago

We recently updated to the latest Steamworks.NET from 14.0 and are getting a hard unity crash when calling SteamNetworkingUtils.SetConfigValue() as such.

float v = 30000f;
System.Runtime.InteropServices.GCHandle floatHandle = System.Runtime.InteropServices.GCHandle.Alloc(v,System.Runtime.InteropServices.GCHandleType.Pinned);

int enabledInt = 1;
System.Runtime.InteropServices.GCHandle enabledIntHandle = System.Runtime.InteropServices.GCHandle.Alloc(enabledInt,System.Runtime.InteropServices.GCHandleType.Pinned);

int dataRate = 150 * 1024;
System.Runtime.InteropServices.GCHandle datarateHandle = System.Runtime.InteropServices.GCHandle.Alloc(dataRate,System.Runtime.InteropServices.GCHandleType.Pinned);

SteamNetworkingUtils.SetConfigValue(ESteamNetworkingConfigValue.k_ESteamNetworkingConfig_TimeoutConnected,ESteamNetworkingConfigScope.k_ESteamNetworkingConfig_Global,System.IntPtr.Zero,ESteamNetworkingConfigDataType.k_ESteamNetworkingConfig_Float,floatHandle.AddrOfPinnedObject() );  
SteamNetworkingUtils.SetConfigValue(ESteamNetworkingConfigValue.k_ESteamNetworkingConfig_IP_AllowWithoutAuth,ESteamNetworkingConfigScope.k_ESteamNetworkingConfig_Global,System.IntPtr.Zero,ESteamNetworkingConfigDataType.k_ESteamNetworkingConfig_Int32,enabledIntHandle.AddrOfPinnedObject() );  

//set datarate limit
SteamNetworkingUtils.SetConfigValue(ESteamNetworkingConfigValue.k_ESteamNetworkingConfig_SendRateMin,ESteamNetworkingConfigScope.k_ESteamNetworkingConfig_Global,System.IntPtr.Zero,ESteamNetworkingConfigDataType.k_ESteamNetworkingConfig_Int32,datarateHandle.AddrOfPinnedObject() );    
SteamNetworkingUtils.SetConfigValue(ESteamNetworkingConfigValue.k_ESteamNetworkingConfig_SendRateMax,ESteamNetworkingConfigScope.k_ESteamNetworkingConfig_Global,System.IntPtr.Zero,ESteamNetworkingConfigDataType.k_ESteamNetworkingConfig_Int32,datarateHandle.AddrOfPinnedObject() );    

With the following stack trace from the Editor.log. I've attached the full crash logs. Editor.log error.log

0x00007FFA1AF43DFC (steamclient64) Breakpad_SteamWriteMiniDumpUsingExceptionInfoWithBuildId 0x00007FFA1AF3ED20 (steamclient64) Breakpad_SteamWriteMiniDumpUsingExceptionInfoWithBuildId 0x000002C16CA9F9D4 (Mono JIT Code) (wrapper managed-to-native) Steamworks.NativeMethods:ISteamNetworkingUtils_SetConfigValue (intptr,Steamworks.ESteamNetworkingConfigValue,Steamworks.ESteamNetworkingConfigScope,intptr,Steamworks.ESteamNetworkingConfigDataType,intptr) 0x000002C16CA9F753 (Mono JIT Code) [C:\Dev\thegreen\TheGreen\Assets\3rd party\Steamworks.NET\autogen\isteamnetworkingutils.cs:321] Steamworks.SteamNetworkingUtils:SetConfigValue (Steamworks.ESteamNetworkingConfigValue,Steamworks.ESteamNetworkingConfigScope,intptr,Steamworks.ESteamNetworkingConfigDataType,intptr) 0x000002C16CA9E6FB (Mono JIT Code) [C:\Dev\thegreen\TheGreen\Assets\Scripts\net\ZSteamSocket.cs:138] ZSteamSocket:RegisterGlobalCallbacks () 0x000002C16CA9E023 (Mono JIT Code) [C:\Dev\thegreen\TheGreen\Assets\Scripts\net\ZSteamSocket.cs:23] ZSteamSocket:.ctor () 0x000002C16CA8A4E3 (Mono JIT Code) [C:\Dev\thegreen\TheGreen\Assets\Scripts\net\ZNet.cs:195] ZNet:Awake () 0x000002C1788E6B48 (Mono JIT Code) (wrapper runtime-invoke) object:runtime_invoke_voidthis (object,intptr,intptr,intptr) 0x00007FFA1EA8E280 (mono-2.0-bdwgc) [c:\build\output\unity-technologies\mono\mono\mini\mini-runtime.c:2813] mono_jit_runtime_invoke 0x00007FFA1EA12AE2 (mono-2.0-bdwgc) [c:\build\output\unity-technologies\mono\mono\metadata\object.c:2921] do_runtime_invoke 0x00007FFA1EA1BB3F (mono-2.0-bdwgc) [c:\build\output\unity-technologies\mono\mono\metadata\object.c:2968] mono_runtime_invoke 0x00007FF7D0A53F3E (Unity) scripting_method_invoke 0x00007FF7D0A4D98D (Unity) ScriptingInvocation::Invoke 0x00007FF7D0A4DC5E (Unity) ScriptingInvocation::InvokeChecked 0x00007FF7D0AB5716 (Unity) SerializableManagedRef::CallMethod 0x00007FF7D0A1050D (Unity) MonoBehaviour::CallAwake 0x00007FF7D0A0EEEF (Unity) MonoBehaviour::AddToManager 0x00007FF7D0A0F93C (Unity) MonoBehaviour::AwakeFromLoad 0x00007FF7CF0CDDD6 (Unity) AwakeFromLoadQueue::InvokePersistentManagerAwake 0x00007FF7CF0CE8A0 (Unity) AwakeFromLoadQueue::PersistentManagerAwakeFromLoad 0x00007FF7D0504553 (Unity) LoadSceneOperation::CompleteAwakeSequence 0x00007FF7D05047F0 (Unity) LoadSceneOperation::CompletePreloadManagerLoadSceneEditor 0x00007FF7D05054A9 (Unity) LoadSceneOperation::IntegrateMainThread 0x00007FF7D0508D49 (Unity) PreloadManager::UpdatePreloadingSingleStep 0x00007FF7D050952F (Unity) PreloadManager::WaitForAllAsyncOperationsToComplete 0x00007FF7CED71838 (Unity) EditorSceneManager::RestoreSceneBackups 0x00007FF7CE7B8774 (Unity) PlayerLoopController::EnterPlayMode 0x00007FF7CE7CAF45 (Unity) PlayerLoopController::SetIsPlaying 0x00007FF7CE7CDC32 (Unity) Application::TickTimer 0x00007FF7CF16B5B5 (Unity) MainMessageLoop 0x00007FF7CF1757C8 (Unity) WinMain 0x00007FF7D2269472 (Unity) __scrt_common_main_seh 0x00007FFAC2737034 (KERNEL32) BaseThreadInitThunk 0x00007FFAC2FE2651 (ntdll) RtlUserThreadStart

This worked fine before the update. Has anything been changed recently that can be causing this and are there any tips on how to get this working again?

Thanks!

Angelyr commented 2 years ago

Have you found any workarounds for this problem?

jsmars commented 2 years ago

Sadly not yet. Our main need for upgrading at the moment however was to get access to the IsSteamRunningOnSteamDeck(), and after some correspondence with valve, we opted for a workaround there to make our own function for that, as it under the hood currently simply checks for the environment variable "SteamDeck" is greater than 0. Important note though, this is not completely future proof as they may change the implementation of that in the future.

rlabrecque commented 2 years ago

I haven't had time to look into this yet unfortunately.

Just to confirm @jsmars, was IsSteamRunningOnSteamDeck() working for you while this crash was occuring? I ask because my initial thoughts were possibly a DLL version mismatch, like old DLL's stuck around from pre-upgrading especially if you upgraded from 15.0.0 or older.

jsmars commented 2 years ago

I'm pretty sure I cleared up the old dirs and cleared all temp files, but not sure where any old DLL's might be hanging around?

Steam can initialize though, and IsRunningOnSteamDeck() does return a value, so everything else we are using seems to be working up until the point we try to create a server, it's when an actual server is started and those lines of code are run that unity itself hard crashed (or the build game exe).

rlabrecque commented 2 years ago

Thanks, will be able to look into this tomorrow!

wappenull commented 1 year ago

Small addition to this. For steam socket networking options, it is better to set these option on creating connection rather than calling SteamNetworkingUtils.SetConfigValue later as quoted from Steam DOC

If you need to set any initial config options, pass them here. See SteamNetworkingConfigValue_t for more about why this is preferable to setting the options "immediately" after creation.

In a few places we need to set configuration options on listen sockets and connections, and have them take effect before the listen socket or connection really starts doing anything. Creating the object and then setting the options "immediately" after creation doesn't work completely, because network packets could be received between the time the object is created and when the options are applied. To set options at creation time in a reliable way, they must be passed to the creation function. This structure is used to pass those options.

For example

in network connection creation, last 2 arguments. Let SteamNetworkingConfigValue_t[] options Client - SteamNetworkingSockets.ConnectP2P( networkIdentity, virtualPort, options.Length, options ) Server - SteamNetworkingSockets.CreateListenSocketP2P( virtualPort, options.Length, options )

Example on one of the popular network option

k_ESteamNetworkingConfig_SendBufferSize This one is associate to k_EResultLimitExceeded error which happen when too much data to push to network and famously on Valhiem community.

List<SteamNetworkingConfigValue_t> options = new List<SteamNetworkingConfigValue_t>( );

    SteamNetworkingConfigValue_t queueSize = new SteamNetworkingConfigValue_t( );
    queueSize.m_eValue = ESteamNetworkingConfigValue.k_ESteamNetworkingConfig_SendBufferSize;
    queueSize.m_eDataType = ESteamNetworkingConfigDataType.k_ESteamNetworkingConfig_Int32;
    queueSize.m_val.m_int32 = 1024 * 1024; // Raise to 1MB queue size
    options.Add( queueSize );
Idles commented 7 months ago

Hey @rlabrecque, did you ever get a chance to look into this? This crash also reproduces on my end. The reproduction case is as simple as:

unsafe { float percent = 5f; SteamNetworkingUtils.SetConfigValue( ESteamNetworkingConfigValue.k_ESteamNetworkingConfig_FakePacketLoss_Send, ESteamNetworkingConfigScope.k_ESteamNetworkingConfig_Global, IntPtr.Zero, ESteamNetworkingConfigDataType.k_ESteamNetworkingConfig_Float, new IntPtr(&percent) ); }

Edit: ah, my reproduction case no longer reproduces on 20.2.0, so you may be able to close the issue