hadashiA / VContainer

The extra fast, minimum code size, GC-free DI (Dependency Injection) library running on Unity Game Engine.
https://vcontainer.hadashikick.jp
MIT License
2.02k stars 176 forks source link

Missing stacktrace details on unhandled exceptions with IL2CPP builds #711

Open FodderMK opened 1 month ago

FodderMK commented 1 month ago

I'm looking for some thoughts on an issue we encountered.

Unity: 2021.3.41f1 VContainer: v1.16.2 Platform: Android IL2CPP

We had a bug in our code that was difficult to diagnose because it only happened on device and VContainer appeared to be hiding the stacktrace. Below is a minimal example to demonstrate.

Steps to reproduce: 1) Create a new Unity project, add VContainer to it via the package manager. 2) Set the platform to Android and the Scripting Backend to IL2CPP 3) Create a new object on the SampleScene called Root and attach the following script to it

using System;
using VContainer;
using VContainer.Unity;

public class Root : LifetimeScope
{
    protected override void Configure(IContainerBuilder builder)
    {
        builder.Register(_ => new BadDependency(), Lifetime.Singleton);
        builder.RegisterEntryPoint<RootStartable>();
    }
}

public class RootStartable : IStartable
{
    public RootStartable(BadDependency badDependency) { }
    public void Start() { }
}

public class BadDependency
{
    public BadDependency()
    {
        throw new Exception("HIT");
    }
}

If you run the project in-editor you will see an exception similar to:

Exception: HIT
BadDependency..ctor () (at Assets/Scripts/Root.cs:24)
Root+<>c.<Configure>b__0_0 (VContainer.IObjectResolver _) (at Assets/Scripts/Root.cs:9)
VContainer.ContainerBuilderExtensions+<>c__DisplayClass6_0`1[TInterface].<Register>b__0 (VContainer.IObjectResolver container) (at Library/PackageCache/jp.hadashikick.vcontainer@fbc5b06545/Runtime/ContainerBuilderExtensions.cs:59)
[...]
VContainer.Unity.LifetimeScope.Build () (at Library/PackageCache/jp.hadashikick.vcontainer@fbc5b06545/Runtime/Unity/LifetimeScope.cs:217)
VContainer.Unity.LifetimeScope.Awake () (at Library/PackageCache/jp.hadashikick.vcontainer@fbc5b06545/Runtime/Unity/LifetimeScope.cs:146)

If you build and run the project on an Android device you will see an exception similar to:

Exception: HIT
   at VContainer.Unity.LifetimeScope.Awake () [0x0005d] in Library/PackageCache/jp.hadashikick.vcontainer@fbc5b06545/Runtime/Unity/LifetimeScope.cs:146

The line shown in that exception is obviously not at fault here but there's no trace of where the problem actually exists. I was expecting something similar to the editor error; showing (at the very least) which class of ours was throwing. Instead the entire stack seems to be gobbled up by the Awake() method in LifetimeScope.

If I change the Register from function-based registration to simple registration like so:

// builder.Register(_ => new BadDependency(), Lifetime.Singleton);
builder.Register<BadDependency>(Lifetime.Singleton);

then I see a stacktrace with a lot more detail:

Exception: HIT
  at BadDependency..ctor () [0x0000d] in Assets/Scripts/Root.cs:24
  at System.Reflection.RuntimeConstructorInfo.InternalInvoke (System.Object obj, System.Object[] parameters, System.Boolean wrapExceptions) [0x00000] in <00000000000000000000000000000000>:0
  at System.Reflection.RuntimeConstructorInfo.DoInvoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <00000000000000000000000000000000>:0
  at System.Reflection.RuntimeConstructorInfo.Invoke (System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <00000000000000000000000000000000>:0
  at System.Reflection.ConstructorInfo.Invoke (System.Object[] parameters) [0x00000] in <00000000000000000000000000000000>:0
  at VContainer.Internal.ReflectionInjecto

Is this the expected behaviour? Is there something we could be doing to get a more-complete stack trace?