Shared memory between Visual Studio build and MinGW build
Hi folks,
got a strange one here.
I am trying to get two programs to communicate with each other on Windows 10 via shared memory. Both of them are using Boost 1.72, compiled from the same set of headers. I am only using the shared memory portion of boost.
However, one is compiled with Visual studio 2019 community, and the other one is compiled with MinGW 64, g++ version 9.2.0. I have to use MinGW, because I am writing a plugin for another program, which only takes dlls compiled with MinGW.
The program compiled with MinGW creates the shared memory and allocates several objects. Then I started the second program that was compiled with Visual Studio 2019. It was able to find and connect to the managed segment. When I am viewing the segment info from Visual Studio's debugger, everything looks ok. However, when I call get_free_memory(). It spits back 18446744073709551104, which is just bizarre.
Then, when I tried to find_or_construct on the managed segment. It just hangs, apparently stuck in winapi::sleep_tick() with the following tracedll!boost::interprocess::winapi::sleep_tick() Line 1288 C++dll!boost::interprocess::ipcdetail::thread_sleep_tick() Line 187 C++dll!boost::interprocess::spin_wait::yield() Line 128 C++dll!boost::interprocess::ipcdetail::try_based_lockboost::interprocess::ipcdetail::spin_mutex(boost::interprocess::ipcdetail::spin_mutex & m) Line 71 C++dll!boost::interprocess::ipcdetail::spin_mutex::lock() Line 81 C++dll!boost::interprocess::ipcdetail::spin_recursive_mutex::lock() Line 95 C++dll!boost::interprocess::interprocess_recursive_mutex::lock() Line 165 C++dll!boost::interprocess::scoped_lockboost::interprocess::interprocess_recursive_mutex::scoped_lockboost::interprocess::interprocess_recursive_mutex(boost::interprocess::interprocess_recursive_mutex & m) Line 81 C++dll!boost::interprocess::segment_manager
It seems that Boost has different binary layouts of its data structures when compiled with MSVC and MINGW, i.e., they’re not compatible between the two compilers. The result is therefore not unexpected. MAYBE it’s possible to make it work (e.g., compile MSVC code in Release mode), but 1) I wouldn’t bet on it, 2) even if you get it to work it’ll be extremely fragile.
* Stian
From: Boost-users
On Mon, 2 Mar 2020 at 02:11, Stian Zeljko Vrba via Boost-users < boost-users@lists.boost.org> wrote:
It seems that Boost has different binary layouts of its data structures when compiled with MSVC and MINGW, i.e., they’re not compatible between the two compilers.
Erm, gcc and vc will never output the same binary code, I haven't done or seen this, but it must be possible to compile clang (with mingw-gcc) for use with mingw, then with that clang-cl you might stand a chance. Sticking to static libraries, helps already (with exceptions across library boundaries), using C as glue could fix the issue forever. Another, much simpler solution is to ditch mingw and use clang-cl as your main (or support to VC) compiler. Clang can 'theoretically' compile 'anything' (bar bugs in Clang), as long as it's coded in a std that's supported by that version of clang and the code adheres to that std, including but not limited to gcc-extensions and microsoft-extensions (in addition to clang-extensions). Contrary to what Clang claims, Clang is not fast (!!!), but it generates good code and excellent (short) error messages, sometimes better (faster binary) than VC, sometimes worse than VC, it's a crap-shoot, for speed-critical code, compiling bits with VC and bits with Clang after having identified which bits work best which compiler after bench-marking, gives to absolute best result, at least at par with gcc if not better. -- @systemdeg "We value your privacy, click here!" Sod off! - degski "Anyone who believes that exponential growth can go on forever in a finite world is either a madman or an economist" - Kenneth E. Boulding "Growth for the sake of growth is the ideology of the cancer cell" - Edward P. Abbey
Thank you guys. Yah, the problem is that the pieces I am writing are all DLLs. And of course, gcc DLL and Msvc DLLs aren't compatible. Therefore, I HAVE to use two compilers.
So, clang might produce data structure layout that might be compatible with gcc?
One idea I thought about was to forgo data structures entirely. Allocate multiple pieces of named shared memory to hold basic data types. It would would be a book keeping nightmare though. And I am not entirely sure how to deal with mutex locking etc in that case. I don't think standard c++ mutex would work for shared memory...
What do u guys think?
Thank you!
On Monday, March 2, 2020, 09:01:59 AM EST, degski via Boost-users
On 3/03/2020 08:37, Da Xu wrote:
Thank you guys. Yah, the problem is that the pieces I am writing are all DLLs. And of course, gcc DLL and Msvc DLLs aren't compatible. Therefore, I HAVE to use two compilers.
So, clang might produce data structure layout that might be compatible with gcc?
If you confine your shared memory interface to POD types that use well-known-sized fields, then most compilers will produce a compatible binary layout. (With a few quirks to watch out for, such as default padding and potentially different sizes for "int", "long", "size_t", "time_t", etc. It doesn't hurt to explicitly static_assert(sizeof(T) == known_constant) in both compilers.) It's when you introduce non-POD C++ types that you typically run into trouble. For example, library types such as std::string are not guaranteed to have equivalent binary layout across different compilers (or even different compiler versions).
Thank you for the reply.
Right now, I am actually stuck in Boost's segment manager. Its own data structure got scrambled in the memory. I haven't even gotten to where my own data structure gets read.
If I do go with the bare metal approach, I will definitely keep these advice in mind.
Da.
On Monday, March 2, 2020, 06:33:55 PM EST, Gavin Lambert via Boost-users
Thank you guys. Yah, the problem is that the pieces I am writing are all DLLs. And of course, gcc DLL and Msvc DLLs aren't compatible. Therefore, I HAVE to use two compilers.
So, clang might produce data structure layout that might be compatible with gcc?
If you confine your shared memory interface to POD types that use well-known-sized fields, then most compilers will produce a compatible binary layout. (With a few quirks to watch out for, such as default padding and potentially different sizes for "int", "long", "size_t", "time_t", etc. It doesn't hurt to explicitly static_assert(sizeof(T) == known_constant) in both compilers.) It's when you introduce non-POD C++ types that you typically run into trouble. For example, library types such as std::string are not guaranteed to have equivalent binary layout across different compilers (or even different compiler versions). _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org https://lists.boost.org/mailman/listinfo.cgi/boost-users
participants (4)
-
Da Xu
-
degski
-
Gavin Lambert
-
Stian Zeljko Vrba