Bug 12925 - [Linux x86_64] Structs incorrectly passed by-value to native code as parameters
Summary: [Linux x86_64] Structs incorrectly passed by-value to native code as parameters
Status: RESOLVED INVALID
Alias: None
Product: Runtime
Classification: Mono
Component: Interop ()
Version: unspecified
Hardware: PC Linux
: --- normal
Target Milestone: ---
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2013-06-27 16:14 UTC by Robert Rouhani
Modified: 2014-12-01 04:22 UTC (History)
4 users (show)

Tags:
Is this bug a regression?: ---
Last known good build:


Attachments
SSCCE exhibiting the bug (709 bytes, application/gzip)
2013-06-27 16:14 UTC, Robert Rouhani
Details


Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on GitHub or Developer Community with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
RESOLVED INVALID

Description Robert Rouhani 2013-06-27 16:14:45 UTC
Created attachment 4216 [details]
SSCCE exhibiting the bug

Related StackOverflow question: http://stackoverflow.com/q/17331418/1122135

The way that Mono sets up function parameters is incorrect for by-value structs. Other parameters are shifted over, creating some weird bugs and segfaults.

I packaged the SSCCE I posted on the StackOverflow question as a .tar.gz, this is the output I get on my Linux x86_64 system:

STRUCT MANAGED
SIZE: 16
22, (33, 44, 55)
STRUCT NATIVE
SIZE: 16
22, (33.000000, 0.000000, 3.179688)

Passing the structs by reference will fix the issue, but will break API compatibility with the library I'm using that exhibits this behavior. Additionally, when there are more parameters, the first int in the struct becomes the next non-struct parameter and the rest of the parameters get shifted down, with the first int showing up as the last parameter.
Comment 1 Robert Rouhani 2013-06-27 16:19:04 UTC
Additionally, here's some system info that may be of use:

uname -a

Linux rob-arch 3.9.7-1-ARCH #1 SMP PREEMPT Thu Jun 20 22:45:32 CEST 2013 x86_64 GNU/Linux

lscpu

Architecture:          x86_64
CPU op-mode(s):        32-bit, 64-bit
Byte Order:            Little Endian
CPU(s):                8
On-line CPU(s) list:   0-7
Thread(s) per core:    2
Core(s) per socket:    4
Socket(s):             1
NUMA node(s):          1
Vendor ID:             GenuineIntel
CPU family:            6
Model:                 42
Model name:            Intel(R) Core(TM) i7-2600K CPU @ 3.40GHz
Stepping:              7
CPU MHz:               3400.000
BogoMIPS:              7008.49
Virtualization:        VT-x
L1d cache:             32K
L1i cache:             32K
L2 cache:              256K
L3 cache:              8192K
NUMA node0 CPU(s):     0-7
Comment 2 Zoltan Varga 2013-07-24 16:11:55 UTC
I can't reproduce this with mono master (on osx-64 though).
Comment 3 Stefan 2013-10-15 11:42:50 UTC
I can tell that our company gets exactly the same problem with Ubuntu 12.04.2 LTS x64.
We have a struct containing only float members and pass it by value via P/Invoke to a gcc compiled .so library.
In best case the wrong float values arrive on native side but mostly it causes a crash.
The same code works fine on windows with a dll (VSC compiled) equal if 32Bit or 64Bit!
But on Linux x64 the default struct marshalling (by value) with mono fails somehow.
The only way to resolve it quck is to replace all struct passing per value with passing per reference.
Comment 4 Stefan 2013-10-15 11:49:01 UTC
I should add that we are doing a game with Unity Engine 4.2.2 which uses a customized older Mono version. But the same bug applies here as stated by Robert Rouhani. We can confirm what was said the StackOverflow question: http://stackoverflow.com/q/17331418/1122135
Comment 5 Zoltan Varga 2013-10-15 11:58:19 UTC
What is the output of mono --version ?
Comment 6 Stefan 2013-10-15 12:11:11 UTC
it is:
"The program 'mono' is currently not installed.  You can install it by typing:
sudo apt-get install mono-runtime"
and that is because the Unity game engine ships a customized version of mono as library (libmono.so) contained in every game build.
Should be any Mono 2.x version, it is not stated anywhere, see here: http://forum.unity3d.com/threads/150749-Unity-4-and-Mono-2-6
Comment 7 Zoltan Varga 2013-10-15 12:57:27 UTC
If this only happens inside unity, you should report it to them. Unity contains a pretty old version of mono and many bugs were fixed in mono since then.
Comment 8 Stefan 2013-10-15 13:45:05 UTC
I think we can workaround by using struct references for now. I just wanted to add here that we have the same bug as "Robert Rouhani" encountered.
If i get time i might test it with standalone mono app using the current mono version.
If it occures there again I'll post it here.
Comment 9 Zoltan Varga 2014-12-01 04:22:06 UTC
-> NOTABUG.