|
|
As you don't seem to have a reproducible scenario let's see if we can at least find what kind of object is being destroyed when that crash happens to narrow down the problem.
Could you please modify in our plugin script Extend.cs the ReleasePending() function to something like the code below, and then attach here the crash dump and Editor.log generated by Unity.
private static void ReleasePending()
{
lock (_pendingRelease)
{
int numPending = _pendingRelease.Count;
for (int i = 0; i < numPending; ++i)
{
IntPtr cPtr = _pendingRelease[i];
IntPtr nativeType = Noesis.BaseComponent.GetDynamicType(cPtr);
NativeTypeInfo info = GetNativeTypeInfo(nativeType);
Debug.Log($"Releasing '{info.Type}' at {cPtr.ToString("X16")}");
BaseComponent.Release(cPtr);
}
_pendingRelease.RemoveRange(0, numPending);
}
}
|
|
|
|
I provided the logs in a private note, for anyone else looking's information. The primary lines of relevance are:
Releasing 'Noesis.GridViewColumn' at 000002C274967190
UnityEngine.StackTraceUtility:ExtractStackTrace ()
UnityEngine.DebugLogHandler:LogFormat (UnityEngine.LogType,UnityEngine.Object,string,object[])
UnityEngine.Logger:Log (UnityEngine.LogType,object)
UnityEngine.Debug:Log (object)
Noesis.Extend:ReleasePending () (at Packages/NoesisGUI/Runtime/API/Core/Extend.cs:6112)
Noesis.Extend:Update () (at Packages/NoesisGUI/Runtime/API/Core/Extend.cs:6123)
Noesis.View:Update (double) (at Packages/NoesisGUI/Runtime/API/Core/View.cs:366)
NoesisView:UpdateInternal () (at Packages/NoesisGUI/Runtime/NoesisView.cs:1455)
NoesisView:LateUpdate () (at Packages/NoesisGUI/Runtime/NoesisView.cs:1356)
(Filename: Packages/NoesisGUI/Runtime/API/Core/Extend.cs Line: 6112)
[NOESIS/E] Unexpected RefCount(2) deleting object at 000002C27496A4E8
UnityEngine.StackTraceUtility:ExtractStackTrace ()
UnityEngine.DebugLogHandler:LogFormat (UnityEngine.LogType,UnityEngine.Object,string,object[])
UnityEngine.Logger:Log (UnityEngine.LogType,object,UnityEngine.Object)
UnityEngine.Debug:LogError (object,UnityEngine.Object)
NoesisUnity:UnityLog (int,string) (at Packages/NoesisGUI/Runtime/NoesisUnity.cs:360)
Noesis.BaseComponent:Release (intptr) (at Packages/NoesisGUI/Runtime/API/Proxies/BaseComponent.cs:62)
Noesis.Extend:ReleasePending () (at Packages/NoesisGUI/Runtime/API/Core/Extend.cs:6114)
Noesis.Extend:Update () (at Packages/NoesisGUI/Runtime/API/Core/Extend.cs:6123)
Noesis.View:Update (double) (at Packages/NoesisGUI/Runtime/API/Core/View.cs:366)
NoesisView:UpdateInternal () (at Packages/NoesisGUI/Runtime/NoesisView.cs:1455)
NoesisView:LateUpdate () (at Packages/NoesisGUI/Runtime/NoesisView.cs:1356)
(Filename: Packages/NoesisGUI/Runtime/NoesisUnity.cs Line: 360)
Releasing 'Noesis.Binding' at 000002C274A3A4C0
UnityEngine.StackTraceUtility:ExtractStackTrace ()
UnityEngine.DebugLogHandler:LogFormat (UnityEngine.LogType,UnityEngine.Object,string,object[])
UnityEngine.Logger:Log (UnityEngine.LogType,object)
UnityEngine.Debug:Log (object)
Noesis.Extend:ReleasePending () (at Packages/NoesisGUI/Runtime/API/Core/Extend.cs:6112)
Noesis.Extend:Update () (at Packages/NoesisGUI/Runtime/API/Core/Extend.cs:6123)
Noesis.View:Update (double) (at Packages/NoesisGUI/Runtime/API/Core/View.cs:366)
NoesisView:UpdateInternal () (at Packages/NoesisGUI/Runtime/NoesisView.cs:1455)
NoesisView:LateUpdate () (at Packages/NoesisGUI/Runtime/NoesisView.cs:1356)
(Filename: Packages/NoesisGUI/Runtime/API/Core/Extend.cs Line: 6112)
ERROR: InvalidOperationException: Native type 'BaseObject' is not registered | Stacktrace: Noesis.Extend.GetNativeTypeInfo (System.IntPtr nativeType) (at Packages/NoesisGUI/Runtime/API/Core/Extend.cs:468)
Noesis.Extend.ReleasePending () (at Packages/NoesisGUI/Runtime/API/Core/Extend.cs:6111)
Noesis.Extend.Update () (at Packages/NoesisGUI/Runtime/API/Core/Extend.cs:6123)
Noesis.View.Update (System.Double timeInSeconds) (at Packages/NoesisGUI/Runtime/API/Core/View.cs:366)
NoesisView.UpdateInternal () (at Packages/NoesisGUI/Runtime/NoesisView.cs:1455)
NoesisView.LateUpdate () (at Packages/NoesisGUI/Runtime/NoesisView.cs:1356)
UnityEngine.StackTraceUtility:ExtractStackTrace ()
UnityEngine.DebugLogHandler:LogFormat (UnityEngine.LogType,UnityEngine.Object,string,object[])
UnityEngine.Logger:Log (UnityEngine.LogType,object)
UnityEngine.Debug:LogError (object)
(Filename: Assets/Scripts/Utils/Log.cs Line: 80)
InvalidOperationException: Native type 'BaseObject' is not registered
at Noesis.Extend.GetNativeTypeInfo (System.IntPtr nativeType) [0x0004b] in OurGame\Packages\NoesisGUI\Runtime\API\Core\Extend.cs:468
at Noesis.Extend.ReleasePending () [0x00039] in OurGame\Packages\NoesisGUI\Runtime\API\Core\Extend.cs:6111
at Noesis.Extend.Update () [0x00001] in OurGame\Packages\NoesisGUI\Runtime\API\Core\Extend.cs:6123
at Noesis.View.Update (System.Double timeInSeconds) [0x00001] in OurGame\Packages\NoesisGUI\Runtime\API\Core\View.cs:366
at NoesisView.UpdateInternal () [0x0008c] in OurGame\Packages\NoesisGUI\Runtime\NoesisView.cs:1455
at NoesisView.LateUpdate () [0x0000f] in OurGame\Packages\NoesisGUI\Runtime\NoesisView.cs:1356
(Filename: Packages/NoesisGUI/Runtime/API/Core/Extend.cs Line: 468)
The error seems to be primarily related to an attached Behaviour that generates GridViewColumns from a databound ObservableCollection. It doesn't seem to appear when it is not used. I would rather not replace this one, though, because there aren't too many great alternatives to this design from a layout perspective. It seems to have something to do with an unregistered managed object, which is a problem I've ran into before (BaseObject is one of our classes), though this reflection of it is novel. |
|
|
|
Could you please share the behavior that creates the GridViewColumns and the piece of xaml where it is used?
I will try to reproduce the problem myself to work on a solution. |
|
|
|
Sure, sorry for the delay.
The behaviour is
public class GridViewGeneratedColumnBehaviour : Behavior<GridView>
{
public static readonly DependencyProperty ColumnFactoryProperty = DependencyProperty.Register(nameof(ColumnFactory), typeof(IGridViewColumnFactory), typeof(GridViewGeneratedColumnBehaviour), new PropertyMetadata(ColumnFactoryChanged));
public IGridViewColumnFactory ColumnFactory
{
get => (IGridViewColumnFactory)GetValue(ColumnFactoryProperty);
set => SetValue(ColumnFactoryProperty, value);
}
private static void ColumnFactoryChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
(d as GridViewGeneratedColumnBehaviour)?.GenerateColumns();
}
public static readonly DependencyProperty ColumnsProperty = DependencyProperty.Register(nameof(Columns), typeof(IEnumerable), typeof(GridViewGeneratedColumnBehaviour), new PropertyMetadata(ColumnsChanged));
private static void ColumnsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
(d as GridViewGeneratedColumnBehaviour)?.ColumnsChangedInt(d, e);
}
private void ColumnsChangedInt(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (e.NewValue is INotifyCollectionChanged c)
{
c.CollectionChanged += ColumnCollectionChanged;
}
if (e.OldValue is INotifyCollectionChanged o)
{
o.CollectionChanged -= ColumnCollectionChanged;
}
GenerateColumns();
}
private void ColumnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
GenerateColumns();
}
public IEnumerable Columns
{
get => (IEnumerable)GetValue(ColumnsProperty);
set => SetValue(ColumnsProperty, value);
}
protected override void OnAttached()
{
base.OnAttached();
GenerateColumns();
}
private void GenerateColumns()
{
if (AssociatedObject == null || AssociatedObject.Columns == null || Columns == null) return;
AssociatedObject.Columns.Clear();
foreach (var col in Columns)
{
AssociatedObject.Columns.Add(ColumnFactory?.ColumnForData(col));
}
}
}
which is used in XAML like
<ListView ItemsSource="{Binding Candidates}">
<ListView.Resources>
<viewModels:ColumnGenerator x:Key="ColumnGenerator"/>
</ListView.Resources>
<ListView.View>
<GridView AllowsColumnReorder="false">
<i:Interaction.Behaviors>
<viewModels:GridViewGeneratedColumnBehaviour Columns="{Binding Values}" ColumnFactory="{StaticResource ColumnGenerator}"/>
</i:Interaction.Behaviors>
<GridView.ColumnCollection></GridView.ColumnCollection>
</GridView>
</ListView.View>
</ListView>
It seems to especially have problems with empty grid cells for some reason, but I haven't put substantial effort into a detailed reproduction case unfortunately. |
|
|
|
Unfortunately I was not able to reproduce that crash with the provided behavior and xaml.
So I generated a new version of the Noesis library with extra checks and information: https://drive.google.com/file/d/1w0Go6BKB0K5h_-lksxLHO-190v_6pOYl/view?usp=sharing
Could you please give it a try and provide again the crash dump and logs? It should detect when an object is going to be destroyed with 1 or more references and log the type of the object.
You just need to place the new Noesis.dll in the NoesisGUI package folder "Runtime/Libraries/Windows/x86_64". |
|
|
|
I'm sorry to intervene, but I think I was able to reproduce the issue. It may not be exactly related to mentioned classes, but the behaviour is the same: I get an error in logs Unexpected RefCount.. followed by a crash. I've made a repository with a reproducable example: https://github.com/ChernyshevDS/NoesisCrashRepro
Open a project in Unity 2021.3.21f1and run a SampleScene. It should show an UI with two buttons, each of them causes a crash but with different means.
First one creates a ton of MultiBinding objects, which causes a crash after some time.
Second one tries to use a HitResult.VisualHit which causes an immediate crash (not sure if the same bug, may need to create another issue) |
|
|
|
It seems to have something to do when the last row of the GridView is deleted.
I've put in the debug DLL but don't see anything obvious in the logs. It goes straight from complaining about a messed up bbcode parameter (sorry) to the RefCount and then to erroring over BaseObject not being registered.
TrimDiskCacheJob: Current cache size 6mb
NOESIS: BBCode tag '%s' color property value '%s' is not a valid color string
NOESIS: BBCode tag '%s' color property value '%s' is not a valid color string
NOESIS: BBCode tag '%s' color property value '%s' is not a valid color string
NOESIS: BBCode tag '%s' color property value '%s' is not a valid color string
NOESIS: BBCode tag '%s' color property value '%s' is not a valid color string
NOESIS: BBCode tag '%s' color property value '%s' is not a valid color string
NOESIS: BBCode tag '%s' color property value '%s' is not a valid color string
NOESIS: BBCode tag '%s' color property value '%s' is not a valid color string
NOESIS: BBCode tag '%s' color property value '%s' is not a valid color string
NOESIS: BBCode tag '%s' color property value '%s' is not a valid color string
NOESIS: BBCode tag '%s' color property value '%s' is not a valid color string
[NOESIS/E] Unexpected RefCount(2) deleting object at 0000017EF46AFD68
UnityEngine.StackTraceUtility:ExtractStackTrace ()
UnityEngine.DebugLogHandler:LogFormat (UnityEngine.LogType,UnityEngine.Object,string,object[])
UnityEngine.Logger:Log (UnityEngine.LogType,object,UnityEngine.Object)
UnityEngine.Debug:LogError (object,UnityEngine.Object)
NoesisUnity:UnityLog (int,string) (at Packages/NoesisGUI/Runtime/NoesisUnity.cs:360)
Noesis.BaseComponent:Release (intptr) (at Packages/NoesisGUI/Runtime/API/Proxies/BaseComponent.cs:62)
Noesis.Extend:ReleasePending () (at Packages/NoesisGUI/Runtime/API/Core/Extend.cs:6114)
Noesis.Extend:Update () (at Packages/NoesisGUI/Runtime/API/Core/Extend.cs:6123)
Noesis.View:Update (double) (at Packages/NoesisGUI/Runtime/API/Core/View.cs:366)
NoesisView:UpdateInternal () (at Packages/NoesisGUI/Runtime/NoesisView.cs:1455)
NoesisView:LateUpdate () (at Packages/NoesisGUI/Runtime/NoesisView.cs:1356)
(Filename: Packages/NoesisGUI/Runtime/NoesisUnity.cs Line: 360)
ERROR: InvalidOperationException: Native type 'BaseObject' is not registered | Stacktrace: Noesis.Extend.GetNativeTypeInfo (System.IntPtr nativeType) (at Packages/NoesisGUI/Runtime/API/Core/Extend.cs:468)
Noesis.Extend.ReleasePending () (at Packages/NoesisGUI/Runtime/API/Core/Extend.cs:6111)
Noesis.Extend.Update () (at Packages/NoesisGUI/Runtime/API/Core/Extend.cs:6123)
Noesis.View.Update (System.Double timeInSeconds) (at Packages/NoesisGUI/Runtime/API/Core/View.cs:366)
NoesisView.UpdateInternal () (at Packages/NoesisGUI/Runtime/NoesisView.cs:1455)
NoesisView.LateUpdate () (at Packages/NoesisGUI/Runtime/NoesisView.cs:1356)
UnityEngine.StackTraceUtility:ExtractStackTrace ()
UnityEngine.DebugLogHandler:LogFormat (UnityEngine.LogType,UnityEngine.Object,string,object[])
UnityEngine.Logger:Log (UnityEngine.LogType,object)
UnityEngine.Debug:LogError (object)
Game.Log:Error (string) (at Assets/Scripts/Utils/Log.cs:80)
Game.ExceptionHandler:handleException (string,string,UnityEngine.LogType) (at Assets/Scripts/Utils/ExceptionHandler.cs:18)
UnityEngine.Application:CallLogCallback (string,string,UnityEngine.LogType,bool)
I've attached the full logs in a private reply. |
|
|
|
Ah ha!
Okay - so, I figured out the commonality between me and jphyzic's code.
First one creates a ton of MultiBinding objects, which causes a crash after some time.
This is what my code is doing too. Each time the behaviour updates the gridview it recreates each column. That operation does
public class SignatureColumnGenerator : IGridViewColumnFactory
{
public GridViewColumn ColumnForData(object data)
{
if (!(data is SignaturesViewModel.SignatureColumn scd)) return null;
var familyText = new TextBlock();
var familyBinding = new MultiBinding();
familyBinding.Bindings.Add(new Binding("Reference"));
familyBinding.Bindings.Add(new Binding("Detected"));
familyBinding.Converter = new FamilyDisplayConverter();
familyBinding.ConverterParameter = scd;
familyText.SetBinding(RichText.TextProperty, familyBinding);
return new GridViewColumn()
{
Header = scd.SignatureName,
CellTemplate = new DataTemplate()
};
}
[snip some other stuff]
}
When I get rid of the MultiBinding, no more problems. It's something to do with the MultiBinding. |
|
|
|
Thanks a lot for the repro project and the information, I was able to identify the source of the problem.
I will prepare a new library for you to try to verify it doesn't crash anymore. |
|
|
|
Please try the following library: https://drive.google.com/file/d/1M3Oa8nSA9DNbOWeQ90S4oTVc5NN3ttAD/view?usp=sharing
Let me know if the crashes are fixed for you. |
|
|
|
Thanks, I tried this library, but it doesn't help, unfortunately. In fact, any click on UI leads to a crash with the stacktrace ending with:
=================================================================
Managed Stacktrace:
at <unknown> <0xffffffff>
at Noesis.NoesisGUI_PINVOKE:VisualTreeHelper_HitTestHelper <0x000fe>
at Noesis.VisualTreeHelper:HitTestHelper <0x000ea>
at Noesis.VisualTreeHelper:HitTest <0x00182>
at NoesisView:HitTest <0x00262>
at NoesisView:ProcessEvent <0x00802>
at NoesisView:OnGUI <0x0030a>
at System.Object:runtime_invoke_void__this__ <0x00187>
=================================================================
Received signal SIGSEGV
Obtained 28 stack frames
0x0000013db37ec2ff (Mono JIT Code) (wrapper managed-to-native) Noesis.NoesisGUI_PINVOKE:VisualTreeHelper_HitTestHelper (System.Runtime.InteropServices.HandleRef,Noesis.Point&)
0x0000013db37ebdfb (Mono JIT Code) [VisualTreeHelper.cs:257] Noesis.VisualTreeHelper:HitTestHelper (Noesis.Visual,Noesis.Point)
0x0000013db37ebc73 (Mono JIT Code) [VisualTreeHelper.cs:44] Noesis.VisualTreeHelper:HitTest (Noesis.Visual,Noesis.Point)
0x0000013db37eac83 (Mono JIT Code) [NoesisView.cs:1634] NoesisView:HitTest (single,single)
0x0000013dadac7453 (Mono JIT Code) [NoesisView.cs:1679] NoesisView:ProcessEvent (UnityEngine.Event,bool,bool)
0x0000013dadac692b (Mono JIT Code) [NoesisView.cs:1808] NoesisView:OnGUI () |
|
|
|
The patched library I provided was generated for NoesisGUI 3.2.2, which version are you using? |
|
|
|
Oh, I'm sorry, you are right! I didn't realize that I was throwing a 3.2.2 library into a 3.2.1 package, my bad. Now everything seems to work as intended, thank you very much! |
|