Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tests deadlock #1999

Closed
RussKie opened this issue Oct 1, 2019 · 8 comments · Fixed by #2191
Closed

Tests deadlock #1999

RussKie opened this issue Oct 1, 2019 · 8 comments · Fixed by #2191
Assignees
Labels
test-bug Problem in test source code (most likely)

Comments

@RussKie
Copy link
Member

RussKie commented Oct 1, 2019

  • .NET Core Version: 5.0

Problem description:

Running tests from the master branch locally I got tests hung. I have attached a debugger and there was a dozen of hung threads.

9 threads were stuck unable to acquire the lock in NativeWindow.CreateHandle() method (originating stacks were slightly different, but they all ended in the same critical section):
image

1 thread was stuck restoring the default trace listener:
image

2 thread were stuck while writing a trace:
image
image

What appears to have happened is that one test was in a middle of creating a handle and attempted to add a trace, which was locked by another thread, that was restoring the default trace listener:
image

Expected behavior:

No deadlock

Minimal repro:

This is very intermittent...

@RussKie RussKie added the test-bug Problem in test source code (most likely) label Oct 1, 2019
@RussKie
Copy link
Member Author

RussKie commented Oct 1, 2019

Few questions here:

/cc: @hughbe

@weltkante
Copy link
Contributor

Creating a control handle on a non-STA thread is a bad idea, it turns the thread pool thread into a UI thread by allocating a message queue etc. but without telling COM that the thread is STA, so controls using COM internally (e.g. RichTextBox) will be pretty confused, if working at all.

@JeremyKuhne
Copy link
Member

Should all out tests dealing with UI (e.g. instantiating controls) be decorated with StaFactAttribute or WinFormsFactAttribute

I think WinFormsFactAttribute is the right response here

@weltkante
Copy link
Contributor

weltkante commented Oct 2, 2019

@JeremyKuhne do you know if WinFormsFactAttribute will lead to OleInitialize being called? I suspect some of the test failures are due to calling OLE functions on non-STA threads, but STA alone may not be enough for OLE, you probably need to call OleInitialize on the thread as well (WinForms does this in most public code paths which e.g. initialize controls, but when doing testing of internal interop it may be circumvented)

@RussKie
Copy link
Member Author

RussKie commented Oct 2, 2019

/cc: @AArnott any thoughts on the subject?

@merriemcgaw merriemcgaw added this to the 5.0 milestone Oct 3, 2019
@hughbe
Copy link
Contributor

hughbe commented Oct 4, 2019

Could it be that we don’t dispose any controls in the unit tests?

@weltkante
Copy link
Contributor

weltkante commented Oct 4, 2019

I think there are multiple concerns here

The deadlock @RussKie shows is probably just a bug in the NoAssertListener, the TraceListenerCollection has its own lock. I didn't do a full analysis but it looks like you got a lock inversion with the NoAssertListeners lock: one path takes them in order A B the other code path takes them in order B A, leading to a deadlock.

Then there is the whole concern of running tests involving window handles and OLE interop on non-STA threads, which technically is not part of this issue, I just was asking here because people already were discussing the test attributes after my first comment.

Not disposing a control may be a problem, but its not directly related to the deadlock. My first comment about control handle creation was just a general comment without having looked at the problem in detail, sorry for leading the discussion astray.

I still think the whole STA/OLE initialization needs to be examined though, maybe in context of some of the other issues about unstable tests.

@AArnott
Copy link
Contributor

AArnott commented Oct 4, 2019

The WinFormsFactAttribute executes the test on an STA thread and sets up WinFormsSynchronizationContext on that thread. It does nothing else. If OleInitialize or some other code should be run as well before the test starts, I'm happy to oblige. Please file an issue at https://github.com/AArnott/Xunit.StaFact/issues

@ghost ghost added the 🚧 work in progress Work that is current in progress label Oct 24, 2019
RussKie pushed a commit to JeremyKuhne/winforms that referenced this issue Oct 25, 2019
The assert context listener would deadlock sometimes and wasn't particularly
efficient. @weltkante discovered this in dotnet#2184 and encouraged me to rethink
how to approach this.

Also disable flaky test `Application_VisualStyleState_Set_ReturnsExpected` that
also leads to deadlocks.

Fixes dotnet#1999
@ghost ghost removed the 🚧 work in progress Work that is current in progress label Oct 25, 2019
@RussKie RussKie removed this from the 5.0 Preview 1- 4 milestone Apr 20, 2020
@ghost ghost locked as resolved and limited conversation to collaborators Feb 4, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
test-bug Problem in test source code (most likely)
Projects
None yet
6 participants