Skip to content
This repository was archived by the owner on Oct 4, 2021. It is now read-only.

Fixes VSTS Bug 958221: System.ArgumentNullException exception in #8340

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

mkrueger
Copy link
Contributor

@mkrueger mkrueger commented Aug 6, 2019

@mkrueger mkrueger requested a review from a team August 6, 2019 08:51
Copy link
Member

@mrward mrward left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If GetAllExtensions can never be null then I guess this code can be changed:

var allExtensions = (extensionChain.GetAllExtensions () ?? Array.Empty<DocumentControllerExtension>())

Copy link
Member

@slluis slluis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

extensions can only be null if the extension chain has been disposed, which happens when the document controller is disposed. If we are trying to access a disposed object, the bug is somewhere else.

@slluis
Copy link
Member

slluis commented Aug 6, 2019

I'm wondering if MonoDevelopDocumentTrackingService is keeping a reference to a disposed document.

@Therzok
Copy link
Contributor

Therzok commented Aug 6, 2019

@slluis there's some other traces, not just MonoDevelopDocumentTrackingService:

System.Linq.Enumerable.OfType[DocumentControllerExtension](IEnumerable)
MonoDevelop.Ide.Gui.Documents.DocumentController.<GetContents>d__XXX.MoveNext()
System.Linq.Enumerable.TryGetFirst[Object](IEnumerable`1,Boolean&)
System.Linq.Enumerable.FirstOrDefault[Object](IEnumerable`1)
MonoDevelop.Ide.Gui.Documents.DocumentController.GetContent(Type)
MonoDevelop.Ide.Gui.Document.<>c__XXX.<GetContentIncludingAllViews>b__XXX(DocumentController)
System.Linq.Enumerable.SelectEnumerableIterator`2[[MonoDevelop.Ide.Gui.Documents.DocumentController, MonoDevelop.Ide, Version=2.6.0.0, Culture=neutral, PublicKeyToken=3ead7498f347467b],[System.Object, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]].MoveNext()
System.Linq.Enumerable.TryGetFirst[Object](IEnumerable`1,Func`2,Boolean&)
System.Linq.Enumerable.FirstOrDefault[Object](IEnumerable`1,Func`2)
MonoDevelop.Ide.Gui.Document.GetContentIncludingAllViews(Type)
MonoDevelop.Ide.Gui.Document.GetContent(Boolean,Type)
MonoDevelop.Ide.Gui.Document.GetContent[TextEditor](Boolean)
MonoDevelop.Ide.Gui.Document.GetContent[TextEditor]()
MonoDevelop.Ide.Gui.Document.get_Editor()
<addin>.ActiveDocumentChanged(Object,EventArgs)
System.CoreExtensions.SafeInvoke[DocumentEventArgs](EventHandler`1,Object,DocumentEventArgs)

@slluis
Copy link
Member

slluis commented Aug 6, 2019

@Therzok yes, there may be more than one problem.

This is not right though:

ActiveDocumentChanged?.Invoke (this, TryGetActiveDocument ());
activeDocument = e.Document;

activeDocument should be assigned before rising the event.

In any case, caching the active document here is a potential problem. It may happen that TryGetActiveDocument is called before MonoDevelopDocumentTrackingService gets the ActiveDocumentChanged event, in which case it would return a stale document.

@slluis
Copy link
Member

slluis commented Aug 6, 2019

Maybe IdeApp.Workbench.ActiveDocument can return a disposed document when the document is closed? worth checking different scenarios.

@Therzok
Copy link
Contributor

Therzok commented Aug 6, 2019

Looks like the code was changed compared to the initial caching commit. This commit changed it to be assigned after

@mkrueger mkrueger force-pushed the master-vsts958221 branch from e576e6c to f09b97b Compare August 7, 2019 08:39
@mkrueger
Copy link
Contributor Author

mkrueger commented Aug 7, 2019

/fixed the activeDocument assignment - that was wrong.

Y there are different scenarios where that can happen.

@mkrueger
Copy link
Contributor Author

mkrueger commented Aug 7, 2019

How about that ? Just giving cutting the GetContent pipe on disposed Documents ?

@sevoku sevoku requested a review from slluis August 8, 2019 08:33
@sevoku
Copy link
Member

sevoku commented Aug 8, 2019

@mkrueger tests are failing now

@slluis
Copy link
Member

slluis commented Aug 8, 2019

My question still stands. Why is GetContent() being called on a disposed document?

@Therzok
Copy link
Contributor

Therzok commented Aug 8, 2019

Honestly, I think this is a fallout from asynchronizing all the document code. Given we can have a situation where:

var doc = await GetDocument();
await SomethingElse(); // User closes the document in the meantime
...
// This is now disposed
DoSomething (doc);

and the user closes the document in the meantime, it can

@slluis
Copy link
Member

slluis commented Aug 8, 2019

@Therzok we have an event that is raised when a document is closed, so that case can be avoided. I don't agree this is a problem of asynchronizing code.

@Therzok
Copy link
Contributor

Therzok commented Aug 8, 2019

Okay, I think I understand now what's going on, at least for the roslyn stack.

  1. The order of assignment did cause most of the bugs.
  2. SolutionCrawler runs on a background thread, so it might race with the UI thread disposing the document.

@Therzok
Copy link
Contributor

Therzok commented Aug 8, 2019

We also should probably remove the activeDocument from the list when it's closed.

@mkrueger
Copy link
Contributor Author

No idea what you mean with remove active document from the list.
At that point it's no longer an IDE document at that point it's a roslyn document. And does it really make sense if a document gets closed that it's removed from the crawler ?

Just because the IDE document is closed it's not affecting it's contents. Interesting would just be closing a document with changes and discard the changes on close.

@Therzok Therzok added this to the 8.3 milestone Aug 21, 2019
@Therzok
Copy link
Contributor

Therzok commented Aug 21, 2019

@mkrueger We need to modify this test and ensure it passes:

@Therzok
Copy link
Contributor

Therzok commented Sep 5, 2019

Can we split this PR? The roslyn active doc fix is good to merge. Stalling this too long is not really a good idea...

@mkrueger
Copy link
Contributor Author

In general I don't think that this change is harmful. Even if there is a deeper problem it makes the code more solid.

@Therzok
Copy link
Contributor

Therzok commented Oct 25, 2019

I still think Lluis is right, in that it hides a problem, not fixes it.

Base automatically changed from master to main March 9, 2021 14:17
@akoeplinger akoeplinger changed the base branch from main to master March 15, 2021 17:02
Base automatically changed from master to main March 15, 2021 17:03
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants