Bug 38614

Summary: Form creation fails when System.Windows.Forms.XplatUIWin32 was initialized from thread which is already finished
Product: [Mono] Class Libraries Reporter: Paul Gofman <gofmanp>
Component: Windows.FormsAssignee: Bugzilla <bugzilla>
Severity: normal CC: alkpli, gofmanp, mono-bugs+mono
Priority: ---    
Version: master   
Target Milestone: Untriaged   
Hardware: PC   
OS: Linux   
Tags: Is this bug a regression?: ---
Last known good build:
Attachments: Test case

Description Paul Gofman 2016-02-10 10:02:44 UTC
Created attachment 14978 [details]
Test case

I am attaching a test case (compile with 'mcs formsthreads.cs -r:System.Windows.Forms.dll'). This test case works under native .Net and fails with Mono.

The test shows the first forms successfully from a newly created thread, then the second form creation fails with the following stack trace:

System.OutOfMemoryException: Not enough memory to complete operation [GDI+ status: OutOfMemory]
  at System.Drawing.GDIPlus.CheckStatus (Status status) <0x29fa710 + 0x0023a> in <filename unknown>:0 
  at System.Drawing.Graphics.FromHwnd (IntPtr hwnd) <0x2a21bd0 + 0x0041b> in <filename unknown>:0 
  at System.Windows.Forms.XplatUIWin32.GetAutoScaleSize (System.Drawing.Font font) <0x2a21a70 + 0x0002d> in <filename unknown>:0 
  at System.Windows.Forms.XplatUI.GetAutoScaleSize (System.Drawing.Font font) <0x2a21a10 + 0x0002e> in <filename unknown>:0 
  at System.Windows.Forms.Form.GetAutoScaleSize (System.Drawing.Font font) <0x2a219b0 + 0x00027> in <filename unknown>:0 
  at System.Windows.Forms.Form..ctor () <0x29ea340 + 0x0010a> in <filename unknown>:0 
  at (wrapper remoting-invoke-with-check) System.Windows.Forms.Form:.ctor ()
  at FormsThreadsTest.GuiThread () <0x29e3280 + 0x0004c> in <filename unknown>:0 
  at FormsThreadsTest.Main () <0x29e0f10 + 0x000b7> in <filename unknow')

'OutOfMemory' status from GDI+ is due to GdipCreateFromHwnd is supplied with invalid window handle ('FosterWindow' window is closed by the time of the second form creation).
The following scenario happens there:
1. Forms framework is first called from a thread, System.Windows.Forms.XplatUIWin32 ctor is called from it and FosterWindow is created
2. Thread exits, FosterWindow is closed automatically on thread termination
3. As XplatUI is initialized statically the subsequent calls to XplatUI use FosterWindow created previously which is already dead.

I've got this case in a real application (which is native but using .Net from mixed and pure .Net dlls from different threads).
Comment 1 Alexander Köplinger [MSFT] 2016-02-10 23:13:12 UTC
Merged https://github.com/mono/mono/pull/2591