question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

ExecutionEngineException when serialising derived class on mobile

See original GitHub issue

Hi there!

I encounter the following error on mobile when serializing a derived class. This only seems to happen on mobile (iOS, haven’t tested Android yet), and works fine on other platforms:

ExecutionEngineException: Attempting to call method 'DanielLochner.Assets.CreatureCreator.AttachedLimb::Serialize<Unity.Netcode.BufferSerializerWriter>' for which no ahead of time (AOT) code was generated.  Consider increasing the --generic-virtual-method-iterations=1 argument

Here is a link to the script: https://github.com/daniellochner/creature-creator-game/blob/main/Assets/CreatureCreator/Scripts/Runtime/Data/AttachedBodyParts/AttachedLimb.cs

Issue Analytics

  • State:open
  • Created 6 months ago
  • Comments:5 (2 by maintainers)

github_iconTop GitHub Comments

1reaction
daniellochnercommented, Mar 14, 2023

Hi there. I was able to fix the issue by navigating to Build Settings > IL2CPP Code Generation and selecting Faster (smaller) builds instead of Faster runtime.

However according to this forum post, it seems it may affect runtime performance?

0reactions
ShadauxCatcommented, May 9, 2023

Hi Daniel,

I’m sorry this took me so long to get to, but I was finally able to reproduce it. This isn’t something we can easily fix within the 1.x line because it would require breaking changes, but I WAS able to identify a workaround.

It seems that calling a virtual method from an interface method throws off the IL2CPP compiler, but if you make the interface method itself virtual, it works. So instead of what you’re doing currently:

class BaseClass: INetworkSerializable
{
  public void NetworkSerialize<T>(BufferSerializer<T> serializer) where T : IReaderWriter
  {
      Serialize(serializer);
  }

  public virtual void Serialize<T>(BufferSerializer<T> serializer) where T : IReaderWriter
  {
      // code
  }
}

class ChildClass: BaseClass
{
  public override void Serialize<T>(BufferSerializer<T> serializer)
  {
      base.Serialize(serializer);
      // code
  }
}

You can instead write it like this:

class BaseClass: INetworkSerializable
{
  public virtual void NetworkSerialize<T>(BufferSerializer<T> serializer) where T : IReaderWriter
  {
      // code
  }
}

class ChildClass: BaseClass
{
  public override void NetworkSerialize<T>(BufferSerializer<T> serializer)
  {
      base.NetworkSerialize(serializer);
      // code
  }
}

And the IL2CPP compiler is able to generate all the needed AOT implementations for both of those methods.

If you want, you can still use other methods to help with serialization - just make them private and call from with NetworkSerialize(). For example:

class BaseClass: INetworkSerializable
{
  public virtual void NetworkSerialize<T>(BufferSerializer<T> serializer) where T : IReaderWriter
  {
      Serialize(serializer);
  }

  private void Serialize<T>(BufferSerializer<T> serializer) where T : IReaderWriter
  {
      // code
  }
}

class ChildClass: BaseClass
{
  public override void NetworkSerialize<T>(BufferSerializer<T> serializer)
  {
      base.NetworkSerialize(serializer);
      Serialize(serializer);
   }
   
  private void Serialize<T>(BufferSerializer<T> serializer) where T : IReaderWriter
  {
      // code
  }
}

The IL2CPP compiler does manage to generate correct AOT code for non-virtual methods that are called from within NetworkSerialize, but seems to choke on generating override methods that are called from the parent class’s NetworkSerialize.

I hope that helps!

Read more comments on GitHub >

github_iconTop Results From Across the Web

ExecutionEngineException Class (System)
The exception that is thrown when there is an internal error in the execution engine of the common language runtime. This class cannot...
Read more >
c# - How to serialize the base class with derived classes
You can't magically serialize a derived class as it's base because. "...Serialization checks type of instance by calling Object.
Read more >
[Solved]-How to serialize the base class with derived classes-C#
You can't magically serialize a derived class as it's base because. "...Serialization checks type of instance by calling Object.getType() method.
Read more >
Type: System.ExecutionEngineException
This constructor is called by derived class constructors to initialize state in this type. Initializes a new instance of the ExecutionEngineException class.
Read more >
C# Programming IV-1: - sheepsqueezers.com
Classes Derived from the Exception Class. • ExecutionEngineException - Obsolete. The exception that is thrown when there is an internal error in the ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found