Author Topic: Unity crash due to "Attempt to access invalid address" in Substance  (Read 3075 times)

This occurred under Unity 2018.2.14 using Plugin 2.1.

The attached crash report shows it occurring at:

Substance.Engine.dll caused an Access Violation (0xc0000005)
  in module Substance.Engine.dll at 0033:558d24e8.

The line of code in my project it's apparently complaining about is:

DecalGraph.SetInputString("Text", Text);

This is being called in OnValidate in the Editor. However, the same crash occurs if I call this via a simple Inspector button after having previously just modified and Apply'd the SBSAR.

It doesn't seem to matter what input I set. This is the stack trace when I try to set a Float instead:

Quote
C++ Error in InsertNumericValuesIntoArray(), invalid Substance input identifier: 'Font_Size'!
UnityEngine.DebugLogHandler:Internal_Log(LogType, String, Object)
UnityEngine.DebugLogHandler:LogFormat(LogType, Object, String, Object[])
UnityEngine.Logger:Log(LogType, Object)
UnityEngine.Debug:LogError(Object)
Substance.Game.NativeCallbacks:csharpLogCallback(Int32, String)
System.Object:wrapper_native_00007FF8558D4F10(IntPtr, String, Single[], UInt32)
System.Reflection.MonoMethod:InternalInvoke(MonoMethod, Object, Object[], Exception&)
System.Reflection.MonoMethod:Invoke(Object, BindingFlags, Binder, Object[], CultureInfo)
System.Reflection.MethodBase:Invoke(Object, Object[])
System.Delegate:DynamicInvokeImpl(Object[])
System.MulticastDelegate:DynamicInvokeImpl(Object[])
System.Delegate:DynamicInvoke(Object[])
Substance.Game.NativeFunctionsShared:cppSetInput_Float(IntPtr, String, Single[], UInt32)
Substance.Game.NativeFunctions:cppSetInput_Float(IntPtr, String, Single[], UInt32)
Substance.Game.SubstanceGraph:SetInputFloat(String, Single)
GraviaSoftware.Gravia.Code.Controllers.Decals.StaticDecalTextController:RefreshTextures() (at Assets\Code\Controllers\Decals\StaticDecalTextController.cs:64)
GraviaSoftware.Gravia.Code.Editor.StaticDecalTextControllerEditor:OnInspectorGUI() (at Assets\Code\Editor\StaticDecalTextControllerEditor.cs:16)

Even though it claims it is complaining about a property "Font_Size", that property definitely exists in my Graph, and this method work properly as long as I haven't just Apply'd the graph in the inspector.

More on this. Here's some code I'm calling in a script to display the properties of the graph:

Code: [Select]
            var sb = new StringBuilder();
            foreach (var prop in myGraph.GetInputProperties())
            {
                sb.AppendLine($"Prop: {prop.name} - {prop.type}");
            }
            Debug.Log($"Properties: {sb.ToString()}");

If I open Unity fresh, and call this method via a button in the Inpsector, I get the full list of all properties of the graph. If I then edit the graph and press Apply, then call this again, I get an empty list.

So what's going on when pressing Apply that causes so many values to be missing? The only way I can "Fix" the graph is to enter Play mode and then exit. Then I can iterate over the list of graph properties again. Even then, some of the time, when doing that, I get this error in my console:

Quote
OutOfMemoryException: Out of memory
 at (wrapper managed-to-native) System.Object.__icall_wrapper_ves_icall_array_new_specific(intptr,int)
 at Substance.Game.NativeTypes.GetNativeInputs (Substance.Game.SubstanceGraph graph, System.Int32 pNumInputs) [0x00000] in <a7f324179b874bf6be743a4296b96d4e>:0
 at Substance.Game.SubstanceGraph.GetInputProperties () [0x0000c] in <a7f324179b874bf6be743a4296b96d4e>:0
 at GraviaSoftware.Gravia.Code.Controllers.Decals.StaticDecalTextController.RefreshTextures () [0x0000e] in C:\Users\Dan\Documents\GitHub\Gravia\Assets\Code\Controllers\Decals\StaticDecalTextController.cs:61
 at GraviaSoftware.Gravia.Code.Editor.StaticDecalTextControllerEditor.OnInspectorGUI () [0x0002d] in C:\Users\Dan\Documents\GitHub\Gravia\Assets\Code\Editor\StaticDecalTextControllerEditor.cs:16
Last Edit: November 27, 2018, 06:11:50 pm

I've created a test project to demonstrate the issue. (https://www.dropbox.com/s/thekvofyc1uez6c/SubstanceCrasher2.zip?dl=0) Open CrashScene. Now find the SBSAR named "TestSubstance" in the Materials folder. Expand it and select "graph.TestSubstance". Change the Text and/or FontSize property, and hit Apply. Now in the scene, click on the cube, and find its "ChangeFontSizeAndText" component. Click on the Refresh button, and you should start seeing these errors in the log:

Quote
C++ Error in InsertNumericValuesIntoArray(), invalid Substance input identifier: 'FontSize'!
C++ Error in SetStringValue(), invalid Substance input identifier: 'Text'!

Now go back to the "graph.TestSubstance", and change FontSize or Text, and hit Apply again. Unity will crash. This whole process of modifying the graph, and clicking the "Refresh" button on my "ChangeFontSizeAndText" component, sometimes gives different results. Sometimes pressing the Refresh button will cause the crash. Sometimes changing a property on the Graph in the inspector will crash Unity before even hitting Apply. There seem to be a lot of things that can go wrong with this workflow.

Note: This is similar, but not identical, to the test project I provided for the other thread I have.

Last Edit: December 03, 2018, 04:50:57 pm

Hey @dgoyette,

I took a look at your example project and it appears that you are attempting to edit graph variables through your own custom script while the "Play in Editor" mode is not running. Since the graph objects themselves are loaded and unloaded at various times in the editor this is not currently supported.

Thanks, Josh. By "Play in Editor" mode do you mean putting [ExecuteInEditMode] on my script? I did try that, but that didn't improve the behavior. (It still crashes.) However, on the bright side, it seems that if I'm actually in Play mode, I don't have any issues modifying the properties in code. So the takeaway is that we can't use the substance API in Edit mode, only in Play mode?