Closed Bug 1332747 Opened 7 years ago Closed 7 years ago

multiple definition of `std::__throw_x_error causes compilation error in mingw

Categories

(Core :: General, defect)

defect
Not set
normal

Tracking

()

RESOLVED FIXED
mozilla55
Tracking Status
firefox53 --- wontfix
firefox55 --- fixed

People

(Reporter: tjr, Assigned: tjr)

References

(Blocks 1 open bug)

Details

Attachments

(1 file)

On mingw 5.1 (and 5.4) a clean compile of aurora fails with the following errors about the redefinitions of the __throw_x_error functions in throw_gcc.h

/usr/local/lib/gcc/i686-w64-mingw32/5.1.0/../../../../i686-w64-mingw32/lib/../lib/libstdc++.a(functexcept.o): In function `ZSt17__throw_bad_allocv':
/home/worker/mingw-w64-build/gcc-5.1.0-mingw32/i686-w64-mingw32/libstdc++-v3/src/c++11/../../../../../gcc-5.1.0/libstdc++-v3/src/c++11/functexcept.cc:62: multiple definition:__throw_bad_alloc()'
Unified_cpp_angle_src_libGLESv20.o:/home/worker/mingw-w64-build/mozilla-mingw/dist/include/mozilla/throw_gcc.h:36: first defined here
/usr/local/lib/gcc/i686-w64-mingw32/5.1.0/../../../../i686-w64-mingw32/lib/../lib/libstdc++.a(functexcept.o): In function `_exchange_and_add_dispatch':
/home/worker/mingw-w64-build/gcc-5.1.0-mingw32/i686-w64-mingw32/libstdc++-v3/include/ext/atomicity.h:81: multiple definition of `std::__throw_logic_error(char const*)'
../libANGLE/EmulateGLFragColorBroadcast.o:/home/worker/mingw-w64-build/mozilla-mingw/dist/include/mozilla/throw_gcc.h:61: first defined here
/usr/local/lib/gcc/i686-w64-mingw32/5.1.0/../../../../i686-w64-mingw32/lib/../lib/libstdc++.a(functexcept.o): In function `_exchange_and_add_dispatch':
/home/worker/mingw-w64-build/gcc-5.1.0-mingw32/i686-w64-mingw32/libstdc++-v3/include/ext/atomicity.h:81: multiple definition of `std::__throw_length_error(char const*)'
Unified_cpp_angle_src_libGLESv20.o:/home/worker/mingw-w64-build/firefox/gfx/angle/src/libGLESv2/entry_points_egl.cpp:36: first defined here
/usr/local/lib/gcc/i686-w64-mingw32/5.1.0/../../../../i686-w64-mingw32/lib/../lib/libstdc++.a(functexcept.o): In function `_exchange_and_add_dispatch':
/home/worker/mingw-w64-build/gcc-5.1.0-mingw32/i686-w64-mingw32/libstdc++-v3/include/ext/atomicity.h:81: multiple definition of `std::__throw_out_of_range(char const*)'
../libANGLE/Unified_cpp_angle_src_libANGLE5.o:/home/worker/mingw-w64-build/mozilla-mingw/dist/include/mozilla/throw_gcc.h:85: first defined here
/usr/local/lib/gcc/i686-w64-mingw32/5.1.0/../../../../i686-w64-mingw32/lib/../lib/libstdc++.a(functexcept.o): In function `_exchange_and_add_dispatch':
/home/worker/mingw-w64-build/gcc-5.1.0-mingw32/i686-w64-mingw32/libstdc++-v3/include/ext/atomicity.h:81: multiple definition of `std::__throw_overflow_error(char const*)'
../libANGLE/Unified_cpp_angle_src_libANGLE11.o:/home/worker/mingw-w64-build/mozilla-mingw/dist/include/mozilla/throw_gcc.h:103: first defined here
collect2: error: ld returned 1 exit status
/home/worker/mingw-w64-build/firefox/config/rules.mk:800: recipe for target 'libGLESv2.dll' failed
make[5]: *** [libGLESv2.dll] Error 1
/home/worker/mingw-w64-build/firefox/config/recurse.mk:71: recipe for target 'gfx/angle/src/libGLESv2/target' failed
make[4]: *** [gfx/angle/src/libGLESv2/target] Error 2



Additionally, upon the second compilation I actually get a compiler error in gcc!
As an update on this, it only occurs with --enable-debug. I believe it has to do with exporting the __throw functions - some sort of difference in the way mingw and clang handle the combination of 'always inline' and 'export' is my current best guess and what I will investigate.
What happens if you use MOZ_ALWAYS_INLINE_EVEN_DEBUG?
Attachment #8855056 - Flags: review?(nfroyd)
It works! I switched it to that macro and did a try build and they all successfully compiled. 

I don't know why MinGW has different inlining/exporting behavior though. I'll pose the question to Jacek if he has any idea or the time to investigate, but I'm hopeful that doesn't need to block approval.
Assignee: nobody → tom
Flags: needinfo?(jacek)
I don't know what difference in MinGW can cause it. I suspected the fact that we use static linking for libstdc++, meaning that linker tries to include duplicated function in resulting binary. Other theory is that lack of support for GC sections could cause variants from libstdc++ to be linked even if they are not used.

Anyway, proposed MOZ_ALWAYS_INLINE_EVEN_DEBUG solution sounds great to me.
Flags: needinfo?(jacek)
Comment on attachment 8855056 [details]
Bug 1332747 Change MOZ_ALWAYS_INLINE to MOZ_ALWAYS_INLINE_EVEN_DEBUG to fix MinGW Debug build

https://reviewboard.mozilla.org/r/126958/#review131482

Sorry for the delay in responding here.

::: memory/mozalloc/throw_gcc.h:41
(Diff revision 2)
>  
>  // NB: user code is not supposed to touch the std:: namespace.  We're
>  // doing this after careful review because we want to define our own
>  // exception throwing semantics.  Don't try this at home!
>  
> -MOZ_THROW_NORETURN MOZ_EXPORT MOZ_ALWAYS_INLINE void
> +MOZ_THROW_NORETURN MOZ_EXPORT MOZ_ALWAYS_INLINE_EVEN_DEBUG void

I'm inclined to say that we should only be enabling `MOZ_ALWAYS_INLINE_EVEN_DEBUG` for mingw only, since that's the only platform that has issues and inlining all of this might not result in the greatest debugging experience otherwise.
Attachment #8855056 - Flags: review?(nfroyd) → review+
Thanks! I used a new macro to switch between the two, I just want to double check that this is okay with you and then I'll mark it for check-in.
Flags: needinfo?(nfroyd)
Comment on attachment 8855056 [details]
Bug 1332747 Change MOZ_ALWAYS_INLINE to MOZ_ALWAYS_INLINE_EVEN_DEBUG to fix MinGW Debug build

https://reviewboard.mozilla.org/r/126958/#review131506

::: memory/mozalloc/throw_gcc.h:41
(Diff revisions 2 - 3)
> -MOZ_THROW_NORETURN MOZ_EXPORT MOZ_ALWAYS_INLINE_EVEN_DEBUG void
> +#ifdef __MINGW32__
> +// MinGW doesn't appropriately inline these functions in debug builds,
> +// so we need to do some extra coercion for it to do so. Bug 1332747
> +#define MOZ_INLINE MOZ_ALWAYS_INLINE_EVEN_DEBUG
> +#else
> +#define MOZ_INLINE MOZ_ALWAYS_INLINE
> +#endif

This looks good.  Please `#undef MOZ_INLINE` at the end of the file so it doesn't leak out into the wild.  It might also be a good idea to call it `MOZ_THROW_INLINE`, similarly to `MOZ_THROW_NORETURN`.
Commented!
Flags: needinfo?(nfroyd)
Thank you!
Autoland can't push this until all pending issues are marked as resolved in MozReview.
Keywords: checkin-needed
Pushed by ryanvm@gmail.com:
https://hg.mozilla.org/integration/autoland/rev/53430e392a6f
Change MOZ_ALWAYS_INLINE to MOZ_ALWAYS_INLINE_EVEN_DEBUG to fix MinGW Debug build r=froydnj
Keywords: checkin-needed
https://hg.mozilla.org/mozilla-central/rev/53430e392a6f
Status: NEW → RESOLVED
Closed: 7 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla55
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: