[Exception] iOS IL2CPP .NET4.x Compatibility


#1

Hi -

I recently upgraded my project to 2018.03.0f2 and would like to upgrade to .NET4.x, using IL2CPP, building for iOS but am receiving exceptions crashing the app due to A* (details below). I am using the latest A* package 4.2.4. It works fine (does not throw an exception when building for .NET2.0 but crashes when switching to .NET4.x.

Please let me know if you have more info on this.

Crashlytics] Exception stack trace: Pathfinding.Util.ObjectPool`1[T].Release (T& obj) (at <00000000000000000000000000000000>:0)

Pathfinding.RichPath.Initialize (Pathfinding.Seeker seeker, Pathfinding.Path path, System.Boolean mergePartEndpoints, System.Boolean simplificationMode) (at <00000000000000000000000000000000>:0)

Pathfinding.RichAI.OnPathComplete (Pathfinding.Path p) (at <00000000000000000000000000000000>:0)

Pathfinding.Seeker.OnPathComplete (Pathfinding.Path p, System.Boolean runModifiers, System.Boolean sendCallbacks) (at <00000000000000000000000000000000>:0)

Pathfinding.PathReturnQueue.ReturnPaths (System.Boolean timeSlice) (at <00000000000000000000000000000000>:0)

System.UnhandledExceptionEventHandler:Invoke(Object, UnhandledExceptionEventArgs)

Fabric.Internal.Crashlytics.CrashlyticsInit:HandleLog(String, String, LogType)

UnityEngine.Application:CallLogCallback(String, String, LogType, Boolean)

UnityEngine.UnhandledExceptionHandler:PrintException(String, Exception)

UnityEngine.UnhandledExceptionHandler:HandleUnhandledException(Object, UnhandledExceptionEventArgs)

System.UnhandledExceptionEventHandler:Invoke(Object, UnhandledExceptionEventArgs)

(Filename: ./Runtime/Export/Debug.bindings.h Line: 45)

NullReferenceException: Object reference not set to an instance of an object.

at Pathfinding.Util.ObjectPool`1[T].Release (T& obj) [0x00000] in <00000000000000000000000000000000>:0

at Pathfinding.RichPath.Initialize (Pathfinding.Seeker seeker, Pathfinding.Path path, System.Boolean mergePartEndpoints, System.Boolean simplificationMode) [0x00000] in <00000000000000000000000000000000>:0

at Pathfinding.RichAI.OnPathComplete (Pathfinding.Path p) [0x00000] in <00000000000000000000000000000000>:0

at Pathfinding.Seeker.OnPathComplete (Pathfinding.Path p, System.Boolean runModifiers, System.Boolean sendCallbacks) [0x00000] in <00000000000000000000000000000000>:0

at Pathfinding.PathReturnQueue.ReturnPaths (System.Boolean timeSlice) [0x00000] in <00000000000000000000000000000000>:0

UnityEngine.UnhandledExceptionHandler:PrintException(String, Exception)

UnityEngine.UnhandledExceptionHandler:HandleUnhandledException(Object, UnhandledExceptionEventArgs)

System.UnhandledExceptionEventHandler:Invoke(Object, UnhandledExceptionEventArgs)


#2

@aron_granberg Any chance you’ve been able to verify if this works or not or any suggested workarounds until it’s supported? Thanks!


#3

Hi

I think this might be an IL2CPP bug where it does not properly track reference parameters. I suppose one easy fix (but which will cause more GC pressure) is to disable pooling (check the ‘Optimizations’ tab in the A* Inspector, enable the option called ASTAR_NO_POOLING).
If you can, please do send a bug report to Unity with your project as an attachment. I am not personally able to replicate it as I do not have an iOS device.


#4

I had a similar issue and made this fix. Posted on another thread but never heard back. Not sure if optimal but working for me.

I modified ObjectPool.cs at line 35 and checked for nulls.

public static void Release (ref T obj) {
// obj will be set to null so we need to copy the reference
var tmp = obj;
if (obj != null)
{
ObjectPoolSimple.Release(ref obj);
}
if (tmp != null)
{
tmp.OnEnterPool();
}
}

Everything seems to work now but I am not sure if this is the best way to fix this. Seems to work fine but maybe something should be addressed earlier in the chain? I get the null reference every time richai updates the destination (Repath Rate).

Please reply back if this fixes for you. If so, hopefully Aron can address this in a future update.


#5

@Foulcloud

That code should definitely not be required and if the IL2CPP bug is still there, your code could lead to incorrect behavior (e.g. the OnEnterPool method not being called).
The RichPath.Initialize method already ensures that the argument is non-null when it calls ObjectPool.Release.

You could however change the order in that method so that it becomes

public static void Release (ref T obj) {
	obj.OnEnterPool();
	ObjectPoolSimple<T>.Release(ref obj);
}

#6

Changing the code as Aron mentions appears to resolve the issue on my end. Recommend trying it that way and please reply back if solution works for others. Thanks all.