Hi Vincent,
I currently have all my cases with 64-bit mixed assemblies calling pure .Net working just fine under Wine/Mono (well, almost fine, it looks like I found a bug in Mono System.Windows.Forms cs code, but this is a separate issue), but not with vanilla ones. The following issues are not fixed upstream yet:
1. Loading 32-bit pure assemblies in 64-bit code. The patch you attached some time ago (which includes CorValidateImage implementation) works just fine for me. Do you have any plans for pushing it upstream soon?
2. Mono JIT compiler PTR/I8 issues. I've extended a bit your test case and updated the patch in the Mono bug info. While we are waiting for some reply on this in Mono maybe it is possible to send my patch for wine-mono? I am not sure that it is fully correct (it would in fact require to get familiar with the whole JIT code generation path to make sure), but I presume it is safe to use as: - the changes relate to 64-bit code generation only, 32 bit is not affected anyhow; - as for 64 bit, the changes solely extend what instruction/call parameters are considered valid for JIT code generator. If something was valid without this patch, it will not be affected. If something was invalid and gets touched by the patch incorrectly for some cases, it will likely result in segfault instead of 'invalid il code' exception in the worst case.
3. 64-bit .Net programs constantly crashing on process exit for me (this affects test case with exe and dll you sent previously as well). The crash happens in Mono GC finalizing code triggered by System.Process.Exit call from mscoree CorExitProcess. The immediate crash reason is that some objects touched by GC through its hash tables get NULL vtable pointer somewhere earlier in deinitialization. I did not find the exact reason for this yet, but looked at coree.c in Mono where they just call ExitProcess without anything else, and comment says: "FIXME: This is not currently supported by the runtime.". If I do the same in mscoree CorExitProcess it fixes the issue with crash. Do you think this is a right way to do for now? If yes I could send a patch for this.
Thanks, Paul.
regarding p. 3, please ignore my suggestion to change mscoree cleanup on process exit. I found a true reason for crash and it is more severe then just crash on exit though easy to fix in Mono. The problem concerns the whole sgen garbage collection under x86_64 when using libmono like Wine does. It can be easily reproduced by a trivial .Net assembly calling GC.Collect() twice in Main (the assembly should be compiled and run as 64bit, 32bit is OK). The problem is sgen_marksweep.c bitcount(mword) function which does it wrong when __GNUC__ is defined (I am attaching a trivial patch which fixes it). I will try to submit it to Mono upstream somehow.
On 02/09/2016 05:16 PM, Paul Gofman wrote:
Hi Vincent,
I currently have all my cases with 64-bit mixed assemblies calling pure .Net working just fine under Wine/Mono (well, almost fine, it looks like I found a bug in Mono System.Windows.Forms cs code, but this is a separate issue), but not with vanilla ones. The following issues are not fixed upstream yet:
- Loading 32-bit pure assemblies in 64-bit code. The patch you attached
some time ago (which includes CorValidateImage implementation) works just fine for me. Do you have any plans for pushing it upstream soon?
- Mono JIT compiler PTR/I8 issues. I've extended a bit your test case
and updated the patch in the Mono bug info. While we are waiting for some reply on this in Mono maybe it is possible to send my patch for wine-mono? I am not sure that it is fully correct (it would in fact require to get familiar with the whole JIT code generation path to make sure), but I presume it is safe to use as:
- the changes relate to 64-bit code generation only, 32 bit is not
affected anyhow;
- as for 64 bit, the changes solely extend what instruction/call
parameters are considered valid for JIT code generator. If something was valid without this patch, it will not be affected. If something was invalid and gets touched by the patch incorrectly for some cases, it will likely result in segfault instead of 'invalid il code' exception in the worst case.
- 64-bit .Net programs constantly crashing on process exit for me (this
affects test case with exe and dll you sent previously as well). The crash happens in Mono GC finalizing code triggered by System.Process.Exit call from mscoree CorExitProcess. The immediate crash reason is that some objects touched by GC through its hash tables get NULL vtable pointer somewhere earlier in deinitialization. I did not find the exact reason for this yet, but looked at coree.c in Mono where they just call ExitProcess without anything else, and comment says: "FIXME: This is not currently supported by the runtime.". If I do the same in mscoree CorExitProcess it fixes the issue with crash. Do you think this is a right way to do for now? If yes I could send a patch for this.
Thanks, Paul.
- Loading 32-bit pure assemblies in 64-bit code. The patch you attached
some time ago (which includes CorValidateImage implementation) works just fine for me. Do you have any plans for pushing it upstream soon?
I don't understand the ntdll parts. I just pulled those from Wine Staging.
The server probably needs to have special treatment for .NET images rather than just skipping image format checks.
I can send the _CorValidateImage implementation, but it's not much use without the rest of it.
I need to take more time to look into 2 and 3.
On 02/09/2016 08:01 PM, Vincent Povirk wrote:
I can send the _CorValidateImage implementation, but it's not much use without the rest of it.
Maybe if you could sent _CorValidateImage (either upstream or to staging) wine staging would get a complete implementation (which has binary builds for everything and easy to install for users so far)?
- Mono JIT compiler PTR/I8 issues. I've extended a bit your test case
and updated the patch in the Mono bug info. While we are waiting for some reply on this in Mono maybe it is possible to send my patch for wine-mono? I am not sure that it is fully correct (it would in fact require to get familiar with the whole JIT code generation path to make sure), but I presume it is safe to use as:
- the changes relate to 64-bit code generation only, 32 bit is not
affected anyhow;
- as for 64 bit, the changes solely extend what instruction/call
parameters are considered valid for JIT code generator. If something was valid without this patch, it will not be affected. If something was invalid and gets touched by the patch incorrectly for some cases, it will likely result in segfault instead of 'invalid il code' exception in the worst case.
Changing the set of accepted IL code based on pointer size doesn't seem right to me (and even if it is, amd64 is the wrong thing to check for). The test indicates that .NET accepts the code either way, though it is actually broken on win32.
On 02/09/2016 08:10 PM, Vincent Povirk wrote:
Changing the set of accepted IL code based on pointer size doesn't seem right to me (and even if it is, amd64 is the wrong thing to check for). The test indicates that .NET accepts the code either way, though it is actually broken on win32.
Do you think it worth changing the patch in a way would arch independent (but crashing on such assemblies on x86), or wait for some reply on the bug in Mono for now?
Changing the set of accepted IL code based on pointer size doesn't seem right to me (and even if it is, amd64 is the wrong thing to check for). The test indicates that .NET accepts the code either way, though it is actually broken on win32.
Do you think it worth changing the patch in a way would arch independent (but crashing on such assemblies on x86), or wait for some reply on the bug in Mono for now?
Well, crashing doesn't seem right either, of course.
.NET seems to be very fragile when it encounters code like this, even on win64. I didn't verify this, but the way your test crashes on win32 looks like stack corruption, which really shouldn't happen with code that doesn't access any pointers. So, for Mono it may make more sense to continue rejecting this kind of code, in which case we'd want it in some form in Wine Mono (but it only feels worth it to me if Wine or at least Wine Staging can use it).