Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BUG: Negative server time and C# remainder results in negative index #4

Open
CoolestCatMona opened this issue Mar 18, 2023 · 1 comment

Comments

@CoolestCatMona
Copy link

The following line

_loadedIndex = (int)(Networking.GetServerTimeInMilliseconds() / 1000f / slideDurationSeconds) % imageUrls.Length;

Uses Networking.GetServerTimeInMilliseconds() as well as the remainder operator

This can create an edge case where _loadedIndex is a negative value, causing an out of bounds exception

  • Networking.GetServerTimeInMilliseconds() will return a signed integer (-2,147,483,648 to 2,147,483,647), however the photon call it depends on will return a value between 0 and 4,294,967.295, when the server timestamp is received, it has a chance of wrapping around to a negative number.
  • The remainder operator in C# is different than moduolo and has a tough time dealing with negative numbers, so something like -5 % 4 in C# will return -1, while -5 % 4 when using % as modulo should return 3

Attached is a stacktrace with some personal information removed and some extra logging I added when debugging

2023.03.18 18:56:21 Error      -  [UdonBehaviour] An exception occurred during Udon execution, this UdonBehaviour will be halted.
VRC.Udon.VM.UdonVMException: The VM encountered an error!
Exception Message:
  An exception occurred during EXTERN to 'SystemObjectArray.__Get__SystemInt32__SystemObject'.
      Parameter Addresses: 0x00000009, 0x00000006, 0x00000029
  
  Index was outside the bounds of the array.
----------------------
Program Counter was at: 668
----------------------
Stack Dump:
  0: 0x0000000A
  1: 0x0000000D
----------------------
Heap Dump:
  0x00000000: -7774693031578337865
  0x00000001: SlideshowFrame
  0x00000002: 4294967295
  0x00000003: VRC.SDKBase.VRCUrl[]
  0x00000004: Weather Displays Screens (UnityEngine.MeshRenderer)
  0x00000005: 15
  0x00000006: -4
  0x00000007: VRC.SDK3.Image.VRCImageDownloader
  0x00000008: Weather Displays Screens (VRC.Udon.UdonBehaviour)
  0x00000009: UnityEngine.Texture2D[]
  0x0000000A: 4294967295
  0x0000000B: Weather Displays Screens (VRC.Udon.UdonBehaviour)
  0x0000000C: 108
  0x0000000D: 152
  0x0000000E: Weather Displays Screens (VRC.Udon.UdonBehaviour)
  0x0000000F: LoadNextRecursive
  0x00000010: Update
  0x00000011: 1000
  0x00000012: Loading index {0}
  0x00000013: imageUrls.Length {0}
  0x00000014: _downloadedTextures.Length {0}
  0x00000015: null
  0x00000016: True
  0x00000017: VRC.SDK3.Image.VRCImageDownloader+ImageDownloader
  0x00000018: Image loaded: {0} bytes.
  0x00000019: null
  0x0000001A: Image not loaded: {0}: {1}.
  0x0000001B: 5
  0x0000001C: -878843116
  0x0000001D: -8.788431E+08
  0x0000001E: -878843.1
  0x0000001F: -58589.54
  0x00000020: -58589
  0x00000021: -58589.54296875
  0x00000022: -58589
  0x00000023: 5
  0x00000024: Loading index -4
  0x00000025: 5
  0x00000026: imageUrls.Length 5
  0x00000027: 5
  0x00000028: _downloadedTextures.Length 5
  0x00000029: null
  0x0000002A: null
  0x0000002B: null
  0x0000002C: False
  0x0000002D: Weather Screens LED (Instance) (UnityEngine.Material)
  0x0000002E: null
  0x0000002F: VRC.SDK3.Image.TextureInfo
  0x00000030: [removed]
  0x00000031: VRC.SDK3.Image.VRCImageDownloader+ImageDownloader
  0x00000032: 4194303
  0x00000033: Image loaded: 4194303 bytes.
  0x00000034:  (UnityEngine.Texture2D)
  0x00000035: Unknown
  0x00000036: null
  0x00000037: null
  0x00000038: null
  0x00000039: SystemArray.__get_Length__SystemInt32
  0x0000003A: UnityEngineTexture2DArray.__ctor__SystemInt32__UnityEngineTexture2DArray
  0x0000003B: VRCSDK3ImageVRCImageDownloader.__ctor____VRCSDK3ImageVRCImageDownloader
  0x0000003C: VRCUdonCommonInterfacesIUdonEventReceiver.__SendCustomEventDelayedSeconds__SystemString_SystemSingle_VRCUdonCommonEnumsEventTiming__SystemVoid
  0x0000003D: VRCSDKBaseNetworking.__GetServerTimeInMilliseconds__SystemInt32
  0x0000003E: SystemConvert.__ToSingle__SystemInt32__SystemSingle
  0x0000003F: SystemSingle.__op_Division__SystemSingle_SystemSingle__SystemSingle
  0x00000040: SystemConvert.__ToDouble__SystemSingle__SystemDouble
  0x00000041: SystemMath.__Truncate__SystemDouble__SystemDouble
  0x00000042: SystemConvert.__ToInt32__SystemDouble__SystemInt32
  0x00000043: SystemInt32.__op_Remainder__SystemInt32_SystemInt32__SystemInt32
  0x00000044: SystemString.__Format__SystemString_SystemObject__SystemString
  0x00000045: UnityEngineDebug.__Log__SystemObject__SystemVoid
  0x00000046: SystemObjectArray.__Get__SystemInt32__SystemObject
  0x00000047: UnityEngineObject.__op_Inequality__UnityEngineObject_UnityEngineObject__SystemBoolean
  0x00000048: UnityEngineRenderer.__get_sharedMaterial__UnityEngineMaterial
  0x00000049: UnityEngineMaterial.__set_mainTexture__UnityEngineTexture__SystemVoid
  0x0000004A: VRCSDK3ImageTextureInfo.__ctor____VRCSDK3ImageTextureInfo
  0x0000004B: VRCSDK3ImageTextureInfo.__set_GenerateMipMaps__SystemBoolean
  0x0000004C: VRCSDKBaseVRCUrlArray.__Get__SystemInt32__VRCSDKBaseVRCUrl
  0x0000004D: UnityEngineRenderer.__get_material__UnityEngineMaterial
  0x0000004E: VRCSDK3ImageVRCImageDownloader.__DownloadImage__VRCSDKBaseVRCUrl_UnityEngineMaterial_VRCUdonCommonInterfacesIUdonEventReceiver_VRCSDK3ImageTextureInfo__VRCSDK3ImageIVRCImageDownload
  0x0000004F: VRCSDK3ImageIVRCImageDownload.__get_SizeInMemoryBytes__SystemInt32
  0x00000050: VRCSDK3ImageIVRCImageDownload.__get_Result__UnityEngineTexture2D
  0x00000051: SystemObjectArray.__Set__SystemInt32_SystemObject__SystemVoid
  0x00000052: VRCSDK3ImageIVRCImageDownload.__get_Error__VRCSDK3ImageVRCImageDownloadError
  0x00000053: SystemObject.__ToString__SystemString
  0x00000054: VRCSDK3ImageIVRCImageDownload.__get_ErrorMessage__SystemString
  0x00000055: SystemString.__Format__SystemString_SystemObject_SystemObject__SystemString
  0x00000056: VRCSDK3ImageVRCImageDownloader.__Dispose__SystemVoid
----------------------
Inner Exception:
 ---> VRC.Udon.VM.UdonVMException: An exception occurred during EXTERN to 'SystemObjectArray.__Get__SystemInt32__SystemObject'.
    Parameter Addresses: 0x00000009, 0x00000006, 0x00000029
 ---> System.IndexOutOfRangeException: Index was outside the bounds of the array.
  at VRC.Udon.Wrapper.Modules.ExternSystemObjectArray.__Get__SystemInt32__SystemObject (VRC.Udon.Common.Interfaces.IUdonHeap heap, System.Span`1[T] parameterAddresses) [0x00000] in <00000000000000000000000000000000>:0 
  at ÏÍÌÌÎÌÏÎÎÏÍÏÏÏÍÏÌÍÏÎÍÍÍ.Invoke (System.Object ÌÍÏÌÏÍÍÌÌÌÏÎÍÎÏÍÏÍÌÍÏÏÌ, ÏÌÍÍÎÏÌÎÏÍÌÌÍÏÍÎÍÍÌÏÎÍÏ ÌÍÏÌÏÏÏÎÌÎÏÌÌÏÌÌÏÏÍÍÎÌÎ) [0x00000] in <00000000000000000000000000000000>:0 
  at VRC.Udon.VM.UdonVM.Interpret () [0x00000] in <00000000000000000000000000000000>:0 
  at VRC.Udon.UdonBehaviour.RunProgram (System.UInt32 entryPoint) [0x00000] in <00000000000000000000000000000000>:0 
  at VRC.Udon.UdonBehaviour.RunProgram (System.String eventName) [0x00000] in <00000000000000000000000000000000>:0 
  at VRC.Udon.ClientBindings.UdonEventScheduler.RunScheduledEvents (VRC.Udon.Common.Enums.EventTiming eventTiming) [0x00000] in <00000000000000000000000000000000>:0 
  at VRC.Udon.UdonManager.Update () [0x00000] in <00000000000000000000000000000000>:0 
   --- End of inner exception stack trace ---
  at VRC.Udon.VM.UdonVM.Interpret () [0x00000] in <00000000000000000000000000000000>:0 
  at VRC.Udon.UdonBehaviour.RunProgram (System.UInt32 entryPoint) [0x00000] in <00000000000000000000000000000000>:0 
  at VRC.Udon.UdonBehaviour.RunProgram (System.String eventName) [0x00000] in <00000000000000000000000000000000>:0 
  at VRC.Udon.ClientBindings.UdonEventScheduler.RunScheduledEvents (VRC.Udon.Common.Enums.EventTiming eventTiming) [0x00000] in <00000000000000000000000000000000>:0 
  at VRC.Udon.UdonManager.Update () [0x00000] in <00000000000000000000000000000000>:0 
   --- End of inner exception stack trace ---
  at VRC.Udon.VM.UdonVM.Interpret () [0x00000] in <00000000000000000000000000000000>:0 
  at VRC.Udon.UdonBehaviour.RunProgram (System.UInt32 entryPoint) [0x00000] in <00000000000000000000000000000000>:0 
  at VRC.Udon.UdonBehaviour.RunProgram (System.String eventName) [0x00000] in <00000000000000000000000000000000>:0 
  at VRC.Udon.ClientBindings.UdonEventScheduler.RunScheduledEvents (VRC.Udon.Common.Enums.EventTiming eventTiming) [0x00000] in <00000000000000000000000000000000>:0 
  at VRC.Udon.UdonManager.Update () [0x00000] in <00000000000000000000000000000000>:0 

This issue will occur occasionally given enough time

As a potential fix one could try to implement a modulo function that can handle negative numbers

    public int Mod(int a, int b)
    {
        return ((a % b) + b) % b;
    }

I'm not immediately sure how to handle Networking.GetServerTimeInMilliseconds() returning negative values occasionally

@Thelvaen
Copy link

I just ran into the same issue, and I just went with

Math.Abs(Networking.GetServerTimeInMilliseconds()) to bypass the issue, going "down" instead of "up" when the server time are negative is not really an issue for a fancy Slide Show :)

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

No branches or pull requests

2 participants