[Bug 10467] Making Microsoft .NET 2.0 to work in wine, based on example app FastMD5 1.4 for NET 2.0

wine-bugs at winehq.org wine-bugs at winehq.org
Fri Nov 16 07:05:47 CST 2007


http://bugs.winehq.org/show_bug.cgi?id=10467





--- Comment #1 from Anastasius Focht <focht at gmx.net>  2007-11-16 07:05:45 ---
Created an attachment (id=9195)
 --> (http://bugs.winehq.org/attachment.cgi?id=9195)
expose PEB loader lock to make .NET framework (ui) to work

Hello,

lets make further steps in this mine field :-)

Prerequisite: 

1) wine-0.9.49 (or GIT)
2) successful installation of .NET 2.0 Framework
3) "l_intl.nls" copied from windows installation to wine system32

----

With that stuff in place, starting .NET gui apps will immediately lead to a
crash.

--- snip ---
0:000> .exr -1
ExceptionAddress: 7a2bd897
(mscorwks!AuxUlibIsDLLSynchronizationHeld+0x00000074)
   ExceptionCode: c0000005 (Access violation)
  ExceptionFlags: 00000000
NumberParameters: 2
   Parameter[0]: 00000000
   Parameter[1]: 0000000c
Attempt to read from address 0000000c
--- snip ---

Not a CLR exception this time. Looks like ordinary NULL ptr dereference.
But just in case let's look at CLR stack:

--- snip ---
0:000> !ClrStack
OS Thread Id: 0xf (0)
ESP       EIP     
0034f128 7a2bd897 [NDirectMethodFrameGeneric: 0034f128]
System.Windows.Forms.UnsafeNativeMethods.IntCreateWindowEx(Int32,
System.String, System.String, Int32, Int32, Int32, Int32, Int32,
System.Runtime.InteropServices.HandleRef,
System.Runtime.InteropServices.HandleRef,
System.Runtime.InteropServices.HandleRef, System.Object)
0034f16c 039b44a5
System.Windows.Forms.UnsafeNativeMethods.CreateWindowEx(Int32, System.String,
System.String, Int32, Int32, Int32, Int32, Int32,
System.Runtime.InteropServices.HandleRef,
System.Runtime.InteropServices.HandleRef,
System.Runtime.InteropServices.HandleRef, System.Object)
0034f1a8 039b089b
System.Windows.Forms.NativeWindow.CreateHandle(System.Windows.Forms.CreateParams)
0034f228 02fafe53 System.Windows.Forms.Control.CreateHandle()
0034f288 02fae08b System.Windows.Forms.Application+MarshalingControl..ctor()
0034f290 02fadfea
System.Windows.Forms.Application+ThreadContext.get_MarshalingControl()
0034f2c0 02fad783
System.Windows.Forms.WindowsFormsSynchronizationContext..ctor()
0034f2d0 02facec9
System.Windows.Forms.WindowsFormsSynchronizationContext.InstallIfNeeded()
0034f2fc 02fa9374 System.Windows.Forms.Control..ctor(Boolean)
0034f370 02fa8176 System.Windows.Forms.ScrollableControl..ctor()
0034f380 02fa8046 System.Windows.Forms.ContainerControl..ctor()
0034f390 02fa7e69 System.Windows.Forms.Form..ctor()
0034f3c8 02fa7132 Projekt2.WinForm..ctor()
0034f3d0 02fa710c Projekt2.WinForm.Main()
0034f5e4 79e88f63 [GCFrame: 0034f5e4] 
--- snip ---

Ok, somewhere after UnsafeNativeMethods.IntCreateWindowEx() (= native code
transition) it crashes.
Lets see native code callstack...

--- snip ---
0:000> kb
ChildEBP RetAddr  Args to Child              
0034e98c 005704ea 0034e998 00570472 0012e100
mscorwks!AuxUlibIsDLLSynchronizationHeld+0x74
WARNING: Frame IP not in any known module. Following frames may be wrong.
0034e9a8 6043855a 00050056 00000024 00000000 0x5704ea
0034e9d8 60438bfe 00570472 00050056 00000024 user32!DeferWindowPos+0x2ea
0034ea18 6043de41 00050056 00000024 00000000 user32!DeferWindowPos+0x98e
0034ea58 60405e8a 00050056 00000024 00000000 user32!CallWindowProcA+0x1d1
0034eac8 60408dc2 0034ebe4 00000001 00000001 user32!GetMessagePos+0xda
0034eb28 6040923a 00000003 6045755e 00000001 user32!PeekMessageA+0xca2
0034eb68 60435228 00050056 00000024 00000000 user32!SendMessageW+0x4a
0034ec28 605e75f7 00050056 0034ed88 0034ed80 user32!WINPOS_GetMinMaxInfo+0x238
0034eda8 604321a7 00050056 0034f018 00000001 winex11!CreateWindow+0x327
0034f008 60433a9b 0000013e 0012e100 00000000 user32!SetWindowLongW+0x537
0034f048 79ef064c 00000000 00a14ee8 00000000 user32!CreateWindowExW+0x5b
0034f0e4 009ca83b 0012e100 0034f128 ff3b682a
mscorwks!NDirectGenericStubReturnFromCall
0034f110 039b44a5 0034f1c8 00a14acc 00a14a8c 0x9ca83b
0034f16c 039b089b 00000000 00000000 11000000 0x39b44a5
0034f220 02fafe53 00a13e00 0000000e 0034f278 0x39b089b
0034f280 02fae08b 00a13e00 02fadfea 00a13a20 0x2fafe53
0034f2b8 02fad783 00000001 00a13928 00000000 0x2fae08b
0034f3d0 79e88f63 79e7c2ca 0034f414 0034f460 0x2fad783
0034f3d4 79e7c2ca 0034f414 0034f460 79e88ee4 mscorwks!CallDescrWorker+0x33
..
--- snip ---

Debugging the native code further, one comes to following code snippet..
I commented some parts for better readability:

--- snip ---
mov     eax, large fs:18h    ; return the TEB address
mov     eax, [eax+30h]       ; return the PEB address
mov     eax, [eax+0A0h]      ; PEB+0xA0 -> void *LoaderLock ->
PRTL_CRITICAL_SECTION LoaderLock
push    1                    
add     eax, 0Ch             ; PEB->LoaderLock.OwningThread
..
cmp     dword ptr [eax], 0   ; PEB->LoaderLock.OwningThread *boom*
..
--- snip ---

Well the code checks the PEB loader lock directly probably to prevent any ui
deadlocks caused by multiple threads defer/nested loading ui controls.
Wine does not expose its internal loader lock in PEB (NULL ptr), which leads to
crash.

At this point wine has to make a design decision: expose the loader lock
(critical section) in PEB or dismiss .NET :-)
Unfortunately I don't see another way because if we fake the lock at this point
by using a dummy one in order to protect the real loader lock it might cause
various issues (both locks would have to be synchronized).

Attached is a patch which fixes this.
It assigns the PEB loader lock field to wine internal loader lock at process
startup (dlls/ntdll/loader.c:process_attach)

It works for me (tm) though AJ might find a better place for this.
---------------------------------------

Stay tuned, more goodies to come ...

Regards.


-- 
Configure bugmail: http://bugs.winehq.org/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are watching all bug changes.



More information about the wine-bugs mailing list