icsharpcode / AvaloniaILSpy

Avalonia-based .NET Decompiler (port of ILSpy)
1.5k stars 169 forks source link

Fix crash that sometimes occurs when reloading an assembly #111

Closed sable-starflower closed 2 years ago

sable-starflower commented 2 years ago

I'm not entirely sure why this crash happens, or whether this is the right fix for it, but I figured including a bit of code was better than just pasting a stack trace into an issue. Here's the stack trace:

$ ./ILSpy
Sorry, we crashed
System.InvalidOperationException: Sequence contains no elements
   at System.Linq.ThrowHelper.ThrowNoElementsException()
   at System.Linq.Enumerable.First[TSource](IEnumerable`1 source)
   at ICSharpCode.ILSpy.CSharpLanguage.<>c__DisplayClass22_0.<AddReferenceWarningMessage>b__1(Object <p0>, RoutedEventArgs <p1>) in /home/runner/work/AvaloniaILSpy/AvaloniaILSpy/ILSpy.Core/Languages/CSharpLanguage.cs:line 333
   at Avalonia.Interactivity.EventRoute.RaiseEventImpl(RoutedEventArgs e) in /_/src/Avalonia.Interactivity/EventRoute.cs:line 152
   at Avalonia.Interactivity.EventRoute.RaiseEvent(IInteractive source, RoutedEventArgs e) in /_/src/Avalonia.Interactivity/EventRoute.cs:line 79
   at Avalonia.Interactivity.Interactive.RaiseEvent(RoutedEventArgs e) in /_/src/Avalonia.Interactivity/Interactive.cs:line 123
   at Avalonia.Controls.Button.OnClick() in /_/src/Avalonia.Controls/Button.cs:line 312
   at Avalonia.Controls.Button.OnPointerReleased(PointerReleasedEventArgs e) in /_/src/Avalonia.Controls/Button.cs:line 357
   at Avalonia.Interactivity.RoutedEvent.<>c__DisplayClass23_0.<AddClassHandler>b__0(ValueTuple`2 args) in /_/src/Avalonia.Interactivity/RoutedEvent.cs:line 94
   at System.Reactive.AnonymousObserver`1.OnNextCore(T value) in /_/Rx.NET/Source/src/System.Reactive/AnonymousObserver.cs:line 67
   at System.Reactive.ObserverBase`1.OnNext(T value) in /_/Rx.NET/Source/src/System.Reactive/ObserverBase.cs:line 36
   at System.Reactive.Subjects.Subject`1.OnNext(T value) in /_/Rx.NET/Source/src/System.Reactive/Subjects/Subject.cs:line 145
   at Avalonia.Interactivity.EventRoute.RaiseEventImpl(RoutedEventArgs e) in /_/src/Avalonia.Interactivity/EventRoute.cs:line 148
   at Avalonia.Interactivity.EventRoute.RaiseEvent(IInteractive source, RoutedEventArgs e) in /_/src/Avalonia.Interactivity/EventRoute.cs:line 79
   at Avalonia.Interactivity.Interactive.RaiseEvent(RoutedEventArgs e) in /_/src/Avalonia.Interactivity/Interactive.cs:line 123
   at Avalonia.Input.MouseDevice.MouseUp(IMouseDevice device, UInt64 timestamp, IInputRoot root, Point p, PointerPointProperties props, KeyModifiers inputModifiers) in /_/src/Avalonia.Input/MouseDevice.cs:line 309
   at Avalonia.Input.MouseDevice.ProcessRawEvent(RawPointerEventArgs e) in /_/src/Avalonia.Input/MouseDevice.cs:line 142
   at Avalonia.Input.InputManager.ProcessInput(RawInputEventArgs e) in /_/src/Avalonia.Input/InputManager.cs:line 37
   at Avalonia.X11.X11Window.<ScheduleInput>b__117_0() in /_/src/Avalonia.X11/X11Window.cs:line 730
   at Avalonia.Threading.JobRunner.RunJobs(Nullable`1 priority) in /_/src/Avalonia.Base/Threading/JobRunner.cs:line 37
   at Avalonia.X11.X11PlatformThreading.HandleX11(CancellationToken cancellationToken) in /_/src/Avalonia.X11/X11PlatformThreading.cs:line 169
   at Avalonia.X11.X11PlatformThreading.RunLoop(CancellationToken cancellationToken) in /_/src/Avalonia.X11/X11PlatformThreading.cs:line 245
   at Avalonia.Threading.Dispatcher.MainLoop(CancellationToken cancellationToken) in /_/src/Avalonia.Base/Threading/Dispatcher.cs:line 65
   at Avalonia.Controls.ApplicationLifetimes.ClassicDesktopStyleApplicationLifetime.Start(String[] args) in /_/src/Avalonia.Controls/ApplicationLifetimes/ClassicDesktopStyleApplicationLifetime.cs:line 120
   at Avalonia.ClassicDesktopStyleApplicationLifetimeExtensions.StartWithClassicDesktopLifetime[T](T builder, String[] args, ShutdownMode shutdownMode) in /_/src/Avalonia.Controls/ApplicationLifetimes/ClassicDesktopStyleApplicationLifetime.cs:line 209
   at ICSharpCode.ILSpy.Program.Main(String[] args) in /home/runner/work/AvaloniaILSpy/AvaloniaILSpy/ILSpy/Program.cs:line 22
siegfriedpammer commented 2 years ago

I think the proper fix for this would be https://github.com/icsharpcode/ILSpy/commit/d8f74cf33e9ee06a61d5490771440f487fe83b2c

Using your fix the button is not added/stops working, if the tree node was not expanded previously. Calling EnsureLazyChildren makes sure that the nodes are added before looking for the right one and prevents the crash.

sable-starflower commented 2 years ago

Oh great, thanks! I updated with the suggested fix, feel free to merge if that looks okay.

jeffreye commented 2 years ago

@sable-starflower can you move assemblyNode and its logics inside delegate as https://github.com/icsharpcode/ILSpy/commit/d8f74cf33e9ee06a61d5490771440f487fe83b2c does?

sable-starflower commented 2 years ago

Oh yeah, sorry for missing that. Done!