Message ID | 20190515204721.18722-2-fontaine.fabrice@gmail.com |
---|---|
State | Accepted |
Headers | show |
Series | [1/2] package/libunwind: add cxx exceptionssupport | expand |
Hello Fabrice, On Wed, 15 May 2019 22:47:21 +0200 Fabrice Fontaine <fontaine.fabrice@gmail.com> wrote: > +_Unwind_GetIP is used in build_stack_trace however this function can be > +provided by libunwind so check for it to avoid the following build > +failure: > + > +/home/buildroot/autobuild/run/instance-1/output/host/lib/gcc/arm-buildroot-linux-musleabihf/7.4.0/../../../../arm-buildroot-linux-musleabihf/bin/ld: ./.libs/libmini.a(libmini_la-mini-exceptions.o): in function `build_stack_trace': > +/home/buildroot/autobuild/run/instance-1/output/build/mono-5.20.1.27/mono/mini/mini-exceptions.c:365: undefined reference to `_Unwind_GetIP' > +collect2: error: ld returned 1 exit status I am really not familiar with _Unwind_GetIP, and I haven't done much research, but it seems like _Unwind_GetIP is also provided by libgcc. Did you make some further research to understand what is _Unwind_GetIP ? Or was your analysis just based on "mono needs _Unwind_GetIP, it's provided by libunwind, let's link with it" ? Thomas
Hello Thomas, Le jeu. 16 mai 2019 à 08:29, Thomas Petazzoni <thomas.petazzoni@bootlin.com> a écrit : > > Hello Fabrice, > > On Wed, 15 May 2019 22:47:21 +0200 > Fabrice Fontaine <fontaine.fabrice@gmail.com> wrote: > > > +_Unwind_GetIP is used in build_stack_trace however this function can be > > +provided by libunwind so check for it to avoid the following build > > +failure: > > + > > +/home/buildroot/autobuild/run/instance-1/output/host/lib/gcc/arm-buildroot-linux-musleabihf/7.4.0/../../../../arm-buildroot-linux-musleabihf/bin/ld: ./.libs/libmini.a(libmini_la-mini-exceptions.o): in function `build_stack_trace': > > +/home/buildroot/autobuild/run/instance-1/output/build/mono-5.20.1.27/mono/mini/mini-exceptions.c:365: undefined reference to `_Unwind_GetIP' > > +collect2: error: ld returned 1 exit status > > I am really not familiar with _Unwind_GetIP, and I haven't done much > research, but it seems like _Unwind_GetIP is also provided by libgcc. > > Did you make some further research to understand what is > _Unwind_GetIP ? Or was your analysis just based on "mono needs > _Unwind_GetIP, it's provided by libunwind, let's link with it" ? My analysis was based on the fact that the build failures occured only when libunwind was built before mono. I traced back this error to the installation of unwind.h by libunwind which contains the following definition of _Unwind_GetIP: extern unsigned long _Unwind_GetIP (struct _Unwind_Context *); However, libunwind implements _Unwind_GetIP in src/unwind/GetIP.c only if --enable-cxx-exceptions is defined. On his side, mono includes unwind.h if it's available: #ifdef HAVE_UNWIND_H #include <unwind.h> #endif unwind.h and _Unwind_GetIP can also be provided by glibc but that's not the cause of this build failure on musl. > > Thomas > -- > Thomas Petazzoni, CTO, Bootlin > Embedded Linux and Kernel engineering > https://bootlin.com Best Regards, Fabrice
Hello, +Arnout in case he has some background knowledge on libunwind. On Thu, 16 May 2019 21:43:20 +0200 Fabrice Fontaine <fontaine.fabrice@gmail.com> wrote: > > Did you make some further research to understand what is > > _Unwind_GetIP ? Or was your analysis just based on "mono needs > > _Unwind_GetIP, it's provided by libunwind, let's link with it" ? > My analysis was based on the fact that the build failures occured only > when libunwind was built before mono. > I traced back this error to the installation of unwind.h by libunwind > which contains the following definition of _Unwind_GetIP: > extern unsigned long _Unwind_GetIP (struct _Unwind_Context *); > > However, libunwind implements _Unwind_GetIP in src/unwind/GetIP.c only > if --enable-cxx-exceptions is defined. > > On his side, mono includes unwind.h if it's available: > #ifdef HAVE_UNWIND_H > #include <unwind.h> > #endif > > unwind.h and _Unwind_GetIP can also be provided by glibc but that's > not the cause of this build failure on musl. Hm, did you notice that mono has its own libunwind library, which provides _Unwind_GetIP ? See: external/corert/src/Native/libunwind/src/UnwindLevel1-gcc-ext.c:_LIBUNWIND_EXPORT uintptr_t _Unwind_GetIPInfo(struct _Unwind_Context *context, external/corert/src/Native/libunwind/src/UnwindLevel1-gcc-ext.c: _LIBUNWIND_TRACE_API("_Unwind_GetIPInfo(context=%p)", (void *)context); external/corert/src/Native/libunwind/src/UnwindLevel1-gcc-ext.c: return _Unwind_GetIP(context); external/corert/src/Native/libunwind/src/Unwind-EHABI.cpp: uintptr_t pc = _Unwind_GetIP(context); external/corert/src/Native/libunwind/src/Unwind-sjlj.c:_LIBUNWIND_EXPORT uintptr_t _Unwind_GetIP(struct _Unwind_Context *context) { external/corert/src/Native/libunwind/src/Unwind-sjlj.c: _LIBUNWIND_TRACE_API("_Unwind_GetIP(context=%p) => 0x%lX", context, external/corert/src/Native/libunwind/src/Unwind-sjlj.c:_LIBUNWIND_EXPORT uintptr_t _Unwind_GetIPInfo(struct _Unwind_Context *context, external/corert/src/Native/libunwind/src/Unwind-sjlj.c: _LIBUNWIND_TRACE_API("_Unwind_GetIPInfo(context=%p, %p) => 0x%lX", external/corert/src/Native/libunwind/src/UnwindCursor.hpp: // This matches the behaviour of _Unwind_GetIP on arm. external/corert/src/Native/libunwind/src/UnwindLevel1.c:_LIBUNWIND_EXPORT uintptr_t _Unwind_GetIP(struct _Unwind_Context *context) { external/corert/src/Native/libunwind/src/UnwindLevel1.c: _LIBUNWIND_TRACE_API("_Unwind_GetIP(context=%p) => 0x%" PRIx64, external/corert/src/Native/libunwind/src/Unwind_AppleExtras.cpp:NOT_HERE_BEFORE_10_6(_Unwind_GetIP) external/corert/src/Native/libunwind/src/Unwind_AppleExtras.cpp:NOT_HERE_BEFORE_10_6(_Unwind_GetIPInfo) external/corert/src/Native/libunwind/src/Unwind_AppleExtras.cpp:NOT_HERE_BEFORE_5_0(_Unwind_GetIP) external/corert/src/Native/libunwind/src/Unwind_AppleExtras.cpp:NOT_HERE_BEFORE_5_0(_Unwind_GetIPInfo) external/corert/src/Native/libunwind/include/unwind.h:extern uintptr_t _Unwind_GetIP(struct _Unwind_Context *context); external/corert/src/Native/libunwind/include/unwind.h:uintptr_t _Unwind_GetIP(struct _Unwind_Context *context) { external/corert/src/Native/libunwind/include/unwind.h:// _Unwind_GetIPInfo is a gcc extension that can be called from within a external/corert/src/Native/libunwind/include/unwind.h:// personality handler. Similar to _Unwind_GetIP() but also returns in external/corert/src/Native/libunwind/include/unwind.h:extern uintptr_t _Unwind_GetIPInfo(struct _Unwind_Context *context, Also http://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic.html#LIBGCC-SMAN says _Unwind_GetIP() is supposed to be provided by libgcc_s. On the other hand, glibc and uclibc provide a _Unwind_GetIP macro, but only for ARM. uClibc libubacktrace also contains this: static void backtrace_init (void) { void *handle = dlopen (LIBGCC_S_SO, RTLD_LAZY); if (handle == NULL || ((unwind_backtrace = dlsym (handle, "_Unwind_Backtrace")) == NULL) || ((unwind_getip = dlsym (handle, "_Unwind_GetIP")) == NULL)) { printf(LIBGCC_S_SO " must be installed for backtrace to work\n"); abort(); } } So it looks for _Unwind_GetIP in libgcc. So, I'm really confused by what is supposed to provide _Unwind_GetIP(), and I don't feel comfortable with just saying "libunwind has it, let's use it". Thomas
On 18/05/2019 22:40, Thomas Petazzoni wrote: > Hello, > > +Arnout in case he has some background knowledge on libunwind. > > On Thu, 16 May 2019 21:43:20 +0200 > Fabrice Fontaine <fontaine.fabrice@gmail.com> wrote: > >>> Did you make some further research to understand what is >>> _Unwind_GetIP ? Or was your analysis just based on "mono needs >>> _Unwind_GetIP, it's provided by libunwind, let's link with it" ? >> My analysis was based on the fact that the build failures occured only >> when libunwind was built before mono. >> I traced back this error to the installation of unwind.h by libunwind >> which contains the following definition of _Unwind_GetIP: >> extern unsigned long _Unwind_GetIP (struct _Unwind_Context *); >> >> However, libunwind implements _Unwind_GetIP in src/unwind/GetIP.c only >> if --enable-cxx-exceptions is defined. >> >> On his side, mono includes unwind.h if it's available: >> #ifdef HAVE_UNWIND_H >> #include <unwind.h> >> #endif But mini-exceptions.c calls _Unwind_GetIP independently of that define. It's called depending on MONO_ARCH_HAVE_UNWIND_BACKTRACE, which is set for linux on arm and amd64 (but strangely enough not on arm64). Also, AFAICS gcc will always install unwind.h. So HAVE_UNWIND_H should be set even if libunwind is not built. The real problem is that libunwind and libgcc have different definitions of _Unwind_GetIP() on arm: libgcc defines it as a macro instead of a function. So I would say that libunwind is the real problem: it replaces gcc's unwind.h with its own version, which is not compatible. (It doesn't really replace it; it just puts another unwind.h earlier in the include path.) Thus, it forces any package that expects to link with libgcc's unwind to instead link with libunwind. >> unwind.h and _Unwind_GetIP can also be provided by glibc but that's >> not the cause of this build failure on musl. > > Hm, did you notice that mono has its own libunwind library, which > provides _Unwind_GetIP ? > > See: > > external/corert/src/Native/libunwind/src/UnwindLevel1-gcc-ext.c:_LIBUNWIND_EXPORT uintptr_t _Unwind_GetIPInfo(struct _Unwind_Context *context, > external/corert/src/Native/libunwind/src/UnwindLevel1-gcc-ext.c: _LIBUNWIND_TRACE_API("_Unwind_GetIPInfo(context=%p)", (void *)context); > external/corert/src/Native/libunwind/src/UnwindLevel1-gcc-ext.c: return _Unwind_GetIP(context); > external/corert/src/Native/libunwind/src/Unwind-EHABI.cpp: uintptr_t pc = _Unwind_GetIP(context); > external/corert/src/Native/libunwind/src/Unwind-sjlj.c:_LIBUNWIND_EXPORT uintptr_t _Unwind_GetIP(struct _Unwind_Context *context) { > external/corert/src/Native/libunwind/src/Unwind-sjlj.c: _LIBUNWIND_TRACE_API("_Unwind_GetIP(context=%p) => 0x%lX", context, > external/corert/src/Native/libunwind/src/Unwind-sjlj.c:_LIBUNWIND_EXPORT uintptr_t _Unwind_GetIPInfo(struct _Unwind_Context *context, > external/corert/src/Native/libunwind/src/Unwind-sjlj.c: _LIBUNWIND_TRACE_API("_Unwind_GetIPInfo(context=%p, %p) => 0x%lX", > external/corert/src/Native/libunwind/src/UnwindCursor.hpp: // This matches the behaviour of _Unwind_GetIP on arm. > external/corert/src/Native/libunwind/src/UnwindLevel1.c:_LIBUNWIND_EXPORT uintptr_t _Unwind_GetIP(struct _Unwind_Context *context) { > external/corert/src/Native/libunwind/src/UnwindLevel1.c: _LIBUNWIND_TRACE_API("_Unwind_GetIP(context=%p) => 0x%" PRIx64, > external/corert/src/Native/libunwind/src/Unwind_AppleExtras.cpp:NOT_HERE_BEFORE_10_6(_Unwind_GetIP) > external/corert/src/Native/libunwind/src/Unwind_AppleExtras.cpp:NOT_HERE_BEFORE_10_6(_Unwind_GetIPInfo) > external/corert/src/Native/libunwind/src/Unwind_AppleExtras.cpp:NOT_HERE_BEFORE_5_0(_Unwind_GetIP) > external/corert/src/Native/libunwind/src/Unwind_AppleExtras.cpp:NOT_HERE_BEFORE_5_0(_Unwind_GetIPInfo) This is a (partial?) copy of LLVM, but it is not actually built. The only files that are built are Unwind-EHABI.cpp and libunwind.cpp. And AppleExtras on Darwin. > external/corert/src/Native/libunwind/include/unwind.h:extern uintptr_t _Unwind_GetIP(struct _Unwind_Context *context); > external/corert/src/Native/libunwind/include/unwind.h:uintptr_t _Unwind_GetIP(struct _Unwind_Context *context) { > external/corert/src/Native/libunwind/include/unwind.h:// _Unwind_GetIPInfo is a gcc extension that can be called from within a > external/corert/src/Native/libunwind/include/unwind.h:// personality handler. Similar to _Unwind_GetIP() but also returns in > external/corert/src/Native/libunwind/include/unwind.h:extern uintptr_t _Unwind_GetIPInfo(struct _Unwind_Context *context, The headers, on the other hand, do get added to the include path. Always a good idea to include a header file but not build all of the corresponding sources... > > Also > http://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic.html#LIBGCC-SMAN > says _Unwind_GetIP() is supposed to be provided by libgcc_s. > > On the other hand, glibc and uclibc provide a _Unwind_GetIP macro, but It's a mystery why they do if gcc already provides the same... > only for ARM. uClibc libubacktrace also contains this: > > static void backtrace_init (void) > { > void *handle = dlopen (LIBGCC_S_SO, RTLD_LAZY); > > if (handle == NULL > || ((unwind_backtrace = dlsym (handle, "_Unwind_Backtrace")) == NULL) > || ((unwind_getip = dlsym (handle, "_Unwind_GetIP")) == NULL)) { > printf(LIBGCC_S_SO " must be installed for backtrace to work\n"); > abort(); > } > } > > So it looks for _Unwind_GetIP in libgcc. > > So, I'm really confused by what is supposed to provide _Unwind_GetIP(), > and I don't feel comfortable with just saying "libunwind has it, let's > use it". To me it feels similar to -latomic (which I also don't completely understand): stuff that gets included through some headers that may come from various sources, and you may or may not need to link with some library depending on what happens the be the actual source. Regards, Arnout
Hi All, On Sat, May 25, 2019 at 7:03 PM Arnout Vandecappelle <arnout@mind.be> wrote: > > > > On 18/05/2019 22:40, Thomas Petazzoni wrote: > > Hello, > > > > +Arnout in case he has some background knowledge on libunwind. > > > > On Thu, 16 May 2019 21:43:20 +0200 > > Fabrice Fontaine <fontaine.fabrice@gmail.com> wrote: > > > >>> Did you make some further research to understand what is > >>> _Unwind_GetIP ? Or was your analysis just based on "mono needs > >>> _Unwind_GetIP, it's provided by libunwind, let's link with it" ? > >> My analysis was based on the fact that the build failures occured only > >> when libunwind was built before mono. > >> I traced back this error to the installation of unwind.h by libunwind > >> which contains the following definition of _Unwind_GetIP: > >> extern unsigned long _Unwind_GetIP (struct _Unwind_Context *); > >> > >> However, libunwind implements _Unwind_GetIP in src/unwind/GetIP.c only > >> if --enable-cxx-exceptions is defined. > >> > >> On his side, mono includes unwind.h if it's available: > >> #ifdef HAVE_UNWIND_H > >> #include <unwind.h> > >> #endif > > But mini-exceptions.c calls _Unwind_GetIP independently of that define. It's > called depending on MONO_ARCH_HAVE_UNWIND_BACKTRACE, which is set for linux on > arm and amd64 (but strangely enough not on arm64). > > Also, AFAICS gcc will always install unwind.h. So HAVE_UNWIND_H should be set > even if libunwind is not built. The real problem is that libunwind and libgcc > have different definitions of _Unwind_GetIP() on arm: libgcc defines it as a > macro instead of a function. > > So I would say that libunwind is the real problem: it replaces gcc's unwind.h > with its own version, which is not compatible. (It doesn't really replace it; it > just puts another unwind.h earlier in the include path.) Thus, it forces any > package that expects to link with libgcc's unwind to instead link with libunwind. This patch looks right to me. If BR2_PACKAGE_LIBUNWIND is somewhat selected, it should be built before mono else mono will fail to compile. @Fabrice Fontaine : have you tried to upstream this patch? > > >> unwind.h and _Unwind_GetIP can also be provided by glibc but that's > >> not the cause of this build failure on musl. > > > > Hm, did you notice that mono has its own libunwind library, which > > provides _Unwind_GetIP ? > > > > See: > > > > external/corert/src/Native/libunwind/src/UnwindLevel1-gcc-ext.c:_LIBUNWIND_EXPORT uintptr_t _Unwind_GetIPInfo(struct _Unwind_Context *context, > > external/corert/src/Native/libunwind/src/UnwindLevel1-gcc-ext.c: _LIBUNWIND_TRACE_API("_Unwind_GetIPInfo(context=%p)", (void *)context); > > external/corert/src/Native/libunwind/src/UnwindLevel1-gcc-ext.c: return _Unwind_GetIP(context); > > external/corert/src/Native/libunwind/src/Unwind-EHABI.cpp: uintptr_t pc = _Unwind_GetIP(context); > > external/corert/src/Native/libunwind/src/Unwind-sjlj.c:_LIBUNWIND_EXPORT uintptr_t _Unwind_GetIP(struct _Unwind_Context *context) { > > external/corert/src/Native/libunwind/src/Unwind-sjlj.c: _LIBUNWIND_TRACE_API("_Unwind_GetIP(context=%p) => 0x%lX", context, > > external/corert/src/Native/libunwind/src/Unwind-sjlj.c:_LIBUNWIND_EXPORT uintptr_t _Unwind_GetIPInfo(struct _Unwind_Context *context, > > external/corert/src/Native/libunwind/src/Unwind-sjlj.c: _LIBUNWIND_TRACE_API("_Unwind_GetIPInfo(context=%p, %p) => 0x%lX", > > external/corert/src/Native/libunwind/src/UnwindCursor.hpp: // This matches the behaviour of _Unwind_GetIP on arm. > > external/corert/src/Native/libunwind/src/UnwindLevel1.c:_LIBUNWIND_EXPORT uintptr_t _Unwind_GetIP(struct _Unwind_Context *context) { > > external/corert/src/Native/libunwind/src/UnwindLevel1.c: _LIBUNWIND_TRACE_API("_Unwind_GetIP(context=%p) => 0x%" PRIx64, > > external/corert/src/Native/libunwind/src/Unwind_AppleExtras.cpp:NOT_HERE_BEFORE_10_6(_Unwind_GetIP) > > external/corert/src/Native/libunwind/src/Unwind_AppleExtras.cpp:NOT_HERE_BEFORE_10_6(_Unwind_GetIPInfo) > > external/corert/src/Native/libunwind/src/Unwind_AppleExtras.cpp:NOT_HERE_BEFORE_5_0(_Unwind_GetIP) > > external/corert/src/Native/libunwind/src/Unwind_AppleExtras.cpp:NOT_HERE_BEFORE_5_0(_Unwind_GetIPInfo) > > This is a (partial?) copy of LLVM, but it is not actually built. The only files > that are built are Unwind-EHABI.cpp and libunwind.cpp. And AppleExtras on Darwin. > > > external/corert/src/Native/libunwind/include/unwind.h:extern uintptr_t _Unwind_GetIP(struct _Unwind_Context *context); > > external/corert/src/Native/libunwind/include/unwind.h:uintptr_t _Unwind_GetIP(struct _Unwind_Context *context) { > > external/corert/src/Native/libunwind/include/unwind.h:// _Unwind_GetIPInfo is a gcc extension that can be called from within a > > external/corert/src/Native/libunwind/include/unwind.h:// personality handler. Similar to _Unwind_GetIP() but also returns in > > external/corert/src/Native/libunwind/include/unwind.h:extern uintptr_t _Unwind_GetIPInfo(struct _Unwind_Context *context, > > The headers, on the other hand, do get added to the include path. > > Always a good idea to include a header file but not build all of the > corresponding sources... > > > > > Also > > http://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic.html#LIBGCC-SMAN > > says _Unwind_GetIP() is supposed to be provided by libgcc_s. > > > > On the other hand, glibc and uclibc provide a _Unwind_GetIP macro, but > > It's a mystery why they do if gcc already provides the same... > > > only for ARM. uClibc libubacktrace also contains this: > > > > static void backtrace_init (void) > > { > > void *handle = dlopen (LIBGCC_S_SO, RTLD_LAZY); > > > > if (handle == NULL > > || ((unwind_backtrace = dlsym (handle, "_Unwind_Backtrace")) == NULL) > > || ((unwind_getip = dlsym (handle, "_Unwind_GetIP")) == NULL)) { > > printf(LIBGCC_S_SO " must be installed for backtrace to work\n"); > > abort(); > > } > > } > > > > So it looks for _Unwind_GetIP in libgcc. > > > > So, I'm really confused by what is supposed to provide _Unwind_GetIP(), > > and I don't feel comfortable with just saying "libunwind has it, let's > > use it". > > To me it feels similar to -latomic (which I also don't completely understand): > stuff that gets included through some headers that may come from various > sources, and you may or may not need to link with some library depending on what > happens the be the actual source. > > Regards, > Arnout > > _______________________________________________ > buildroot mailing list > buildroot@busybox.net > http://lists.busybox.net/mailman/listinfo/buildroot
Dear Angelo, Le ven. 16 août 2019 à 09:22, Angelo Compagnucci <angelo@amarulasolutions.com> a écrit : > > Hi All, > > On Sat, May 25, 2019 at 7:03 PM Arnout Vandecappelle <arnout@mind.be> wrote: > > > > > > > > On 18/05/2019 22:40, Thomas Petazzoni wrote: > > > Hello, > > > > > > +Arnout in case he has some background knowledge on libunwind. > > > > > > On Thu, 16 May 2019 21:43:20 +0200 > > > Fabrice Fontaine <fontaine.fabrice@gmail.com> wrote: > > > > > >>> Did you make some further research to understand what is > > >>> _Unwind_GetIP ? Or was your analysis just based on "mono needs > > >>> _Unwind_GetIP, it's provided by libunwind, let's link with it" ? > > >> My analysis was based on the fact that the build failures occured only > > >> when libunwind was built before mono. > > >> I traced back this error to the installation of unwind.h by libunwind > > >> which contains the following definition of _Unwind_GetIP: > > >> extern unsigned long _Unwind_GetIP (struct _Unwind_Context *); > > >> > > >> However, libunwind implements _Unwind_GetIP in src/unwind/GetIP.c only > > >> if --enable-cxx-exceptions is defined. > > >> > > >> On his side, mono includes unwind.h if it's available: > > >> #ifdef HAVE_UNWIND_H > > >> #include <unwind.h> > > >> #endif > > > > But mini-exceptions.c calls _Unwind_GetIP independently of that define. It's > > called depending on MONO_ARCH_HAVE_UNWIND_BACKTRACE, which is set for linux on > > arm and amd64 (but strangely enough not on arm64). > > > > Also, AFAICS gcc will always install unwind.h. So HAVE_UNWIND_H should be set > > even if libunwind is not built. The real problem is that libunwind and libgcc > > have different definitions of _Unwind_GetIP() on arm: libgcc defines it as a > > macro instead of a function. > > > > So I would say that libunwind is the real problem: it replaces gcc's unwind.h > > with its own version, which is not compatible. (It doesn't really replace it; it > > just puts another unwind.h earlier in the include path.) Thus, it forces any > > package that expects to link with libgcc's unwind to instead link with libunwind. > > This patch looks right to me. If BR2_PACKAGE_LIBUNWIND is somewhat > selected, it should be built before mono else mono will fail to > compile. > > @Fabrice Fontaine : have you tried to upstream this patch? Nope, following Arnout 's review I didn't try to upstream it. > > > > > >> unwind.h and _Unwind_GetIP can also be provided by glibc but that's > > >> not the cause of this build failure on musl. > > > > > > Hm, did you notice that mono has its own libunwind library, which > > > provides _Unwind_GetIP ? > > > > > > See: > > > > > > external/corert/src/Native/libunwind/src/UnwindLevel1-gcc-ext.c:_LIBUNWIND_EXPORT uintptr_t _Unwind_GetIPInfo(struct _Unwind_Context *context, > > > external/corert/src/Native/libunwind/src/UnwindLevel1-gcc-ext.c: _LIBUNWIND_TRACE_API("_Unwind_GetIPInfo(context=%p)", (void *)context); > > > external/corert/src/Native/libunwind/src/UnwindLevel1-gcc-ext.c: return _Unwind_GetIP(context); > > > external/corert/src/Native/libunwind/src/Unwind-EHABI.cpp: uintptr_t pc = _Unwind_GetIP(context); > > > external/corert/src/Native/libunwind/src/Unwind-sjlj.c:_LIBUNWIND_EXPORT uintptr_t _Unwind_GetIP(struct _Unwind_Context *context) { > > > external/corert/src/Native/libunwind/src/Unwind-sjlj.c: _LIBUNWIND_TRACE_API("_Unwind_GetIP(context=%p) => 0x%lX", context, > > > external/corert/src/Native/libunwind/src/Unwind-sjlj.c:_LIBUNWIND_EXPORT uintptr_t _Unwind_GetIPInfo(struct _Unwind_Context *context, > > > external/corert/src/Native/libunwind/src/Unwind-sjlj.c: _LIBUNWIND_TRACE_API("_Unwind_GetIPInfo(context=%p, %p) => 0x%lX", > > > external/corert/src/Native/libunwind/src/UnwindCursor.hpp: // This matches the behaviour of _Unwind_GetIP on arm. > > > external/corert/src/Native/libunwind/src/UnwindLevel1.c:_LIBUNWIND_EXPORT uintptr_t _Unwind_GetIP(struct _Unwind_Context *context) { > > > external/corert/src/Native/libunwind/src/UnwindLevel1.c: _LIBUNWIND_TRACE_API("_Unwind_GetIP(context=%p) => 0x%" PRIx64, > > > external/corert/src/Native/libunwind/src/Unwind_AppleExtras.cpp:NOT_HERE_BEFORE_10_6(_Unwind_GetIP) > > > external/corert/src/Native/libunwind/src/Unwind_AppleExtras.cpp:NOT_HERE_BEFORE_10_6(_Unwind_GetIPInfo) > > > external/corert/src/Native/libunwind/src/Unwind_AppleExtras.cpp:NOT_HERE_BEFORE_5_0(_Unwind_GetIP) > > > external/corert/src/Native/libunwind/src/Unwind_AppleExtras.cpp:NOT_HERE_BEFORE_5_0(_Unwind_GetIPInfo) > > > > This is a (partial?) copy of LLVM, but it is not actually built. The only files > > that are built are Unwind-EHABI.cpp and libunwind.cpp. And AppleExtras on Darwin. > > > > > external/corert/src/Native/libunwind/include/unwind.h:extern uintptr_t _Unwind_GetIP(struct _Unwind_Context *context); > > > external/corert/src/Native/libunwind/include/unwind.h:uintptr_t _Unwind_GetIP(struct _Unwind_Context *context) { > > > external/corert/src/Native/libunwind/include/unwind.h:// _Unwind_GetIPInfo is a gcc extension that can be called from within a > > > external/corert/src/Native/libunwind/include/unwind.h:// personality handler. Similar to _Unwind_GetIP() but also returns in > > > external/corert/src/Native/libunwind/include/unwind.h:extern uintptr_t _Unwind_GetIPInfo(struct _Unwind_Context *context, > > > > The headers, on the other hand, do get added to the include path. > > > > Always a good idea to include a header file but not build all of the > > corresponding sources... > > > > > > > > Also > > > http://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic.html#LIBGCC-SMAN > > > says _Unwind_GetIP() is supposed to be provided by libgcc_s. > > > > > > On the other hand, glibc and uclibc provide a _Unwind_GetIP macro, but > > > > It's a mystery why they do if gcc already provides the same... > > > > > only for ARM. uClibc libubacktrace also contains this: > > > > > > static void backtrace_init (void) > > > { > > > void *handle = dlopen (LIBGCC_S_SO, RTLD_LAZY); > > > > > > if (handle == NULL > > > || ((unwind_backtrace = dlsym (handle, "_Unwind_Backtrace")) == NULL) > > > || ((unwind_getip = dlsym (handle, "_Unwind_GetIP")) == NULL)) { > > > printf(LIBGCC_S_SO " must be installed for backtrace to work\n"); > > > abort(); > > > } > > > } > > > > > > So it looks for _Unwind_GetIP in libgcc. > > > > > > So, I'm really confused by what is supposed to provide _Unwind_GetIP(), > > > and I don't feel comfortable with just saying "libunwind has it, let's > > > use it". > > > > To me it feels similar to -latomic (which I also don't completely understand): > > stuff that gets included through some headers that may come from various > > sources, and you may or may not need to link with some library depending on what > > happens the be the actual source. > > > > Regards, > > Arnout > > > > _______________________________________________ > > buildroot mailing list > > buildroot@busybox.net > > http://lists.busybox.net/mailman/listinfo/buildroot Best Regards, Fabrice
Hi all, Thomas and I spent a couple of more hours to get to the bottom of this, and it gets even weirder... On 16/08/2019 10:34, Fabrice Fontaine wrote: > Dear Angelo, > > Le ven. 16 août 2019 à 09:22, Angelo Compagnucci > <angelo@amarulasolutions.com> a écrit : >> >> Hi All, >> >> On Sat, May 25, 2019 at 7:03 PM Arnout Vandecappelle <arnout@mind.be> wrote: >>> >>> >>> >>> On 18/05/2019 22:40, Thomas Petazzoni wrote: >>>> Hello, >>>> >>>> +Arnout in case he has some background knowledge on libunwind. >>>> >>>> On Thu, 16 May 2019 21:43:20 +0200 >>>> Fabrice Fontaine <fontaine.fabrice@gmail.com> wrote: >>>> >>>>>> Did you make some further research to understand what is >>>>>> _Unwind_GetIP ? Or was your analysis just based on "mono needs >>>>>> _Unwind_GetIP, it's provided by libunwind, let's link with it" ? >>>>> My analysis was based on the fact that the build failures occured only >>>>> when libunwind was built before mono. >>>>> I traced back this error to the installation of unwind.h by libunwind >>>>> which contains the following definition of _Unwind_GetIP: >>>>> extern unsigned long _Unwind_GetIP (struct _Unwind_Context *); >>>>> >>>>> However, libunwind implements _Unwind_GetIP in src/unwind/GetIP.c only >>>>> if --enable-cxx-exceptions is defined. >>>>> >>>>> On his side, mono includes unwind.h if it's available: >>>>> #ifdef HAVE_UNWIND_H >>>>> #include <unwind.h> >>>>> #endif >>> >>> But mini-exceptions.c calls _Unwind_GetIP independently of that define. It's >>> called depending on MONO_ARCH_HAVE_UNWIND_BACKTRACE, which is set for linux on >>> arm and amd64 (but strangely enough not on arm64). >>> >>> Also, AFAICS gcc will always install unwind.h. So HAVE_UNWIND_H should be set >>> even if libunwind is not built. The real problem is that libunwind and libgcc >>> have different definitions of _Unwind_GetIP() on arm: libgcc defines it as a >>> macro instead of a function. Indeed, gcc installs a copy of unwind.h, but in a different location. What happens is that normally the unwind.h of gcc is used, because the default search path is GCCDIR/include GCCDIR/../../../../arm-buildroot-linux-gnueabihf/include STAGING_DIR/usr/include (GCCDIR is where cc1 etc. are installed; the second include is where the libstdc++ headers get installed). Because of this order, the unwind.h from gcc is used, and all is well. *However*, in the specific case of a musl toolchain, it is GCCDIR/../../../../arm-buildroot-linux-gnueabihf/include STAGING_DIR/usr/include GCCDIR/include And because this is not yet weird enough: when you move the toolchain to a different location (e.g. when you use it as an external toolchain), the search path of a musl toolchain becomes GCCDIR/../../../../arm-buildroot-linux-gnueabihf/include GCCDIR/include STAGING_DIR/usr/include Therefore, the problem with mono libunwind only occurs for an internal musl toolchain, not for an external one... This is where we gave up... >>> So I would say that libunwind is the real problem: it replaces gcc's unwind.h >>> with its own version, which is not compatible. (It doesn't really replace it; it >>> just puts another unwind.h earlier in the include path.) Thus, it forces any >>> package that expects to link with libgcc's unwind to instead link with libunwind. >> >> This patch looks right to me. If BR2_PACKAGE_LIBUNWIND is somewhat >> selected, it should be built before mono else mono will fail to >> compile. [snip] >>> To me it feels similar to -latomic (which I also don't completely understand): >>> stuff that gets included through some headers that may come from various >>> sources, and you may or may not need to link with some library depending on what >>> happens the be the actual source. In conclusion, the most practical solution is to do this, because it is basically sane: there is an unwind header installed by libunwind, so it makes sense to also link with it. Therefore, I've applied both patches, thanks. Regards, Arnout
diff --git a/package/mono/0003-configure.ac-checks-for-libunwind.patch b/package/mono/0003-configure.ac-checks-for-libunwind.patch new file mode 100644 index 0000000000..8ff6b2f5c7 --- /dev/null +++ b/package/mono/0003-configure.ac-checks-for-libunwind.patch @@ -0,0 +1,40 @@ +From 4dc1d1fe553f3a8ad00919324419aba54675239e Mon Sep 17 00:00:00 2001 +From: Fabrice Fontaine <fontaine.fabrice@gmail.com> +Date: Wed, 15 May 2019 22:30:01 +0200 +Subject: [PATCH] configure.ac: checks for libunwind + +_Unwind_GetIP is used in build_stack_trace however this function can be +provided by libunwind so check for it to avoid the following build +failure: + +/home/buildroot/autobuild/run/instance-1/output/host/lib/gcc/arm-buildroot-linux-musleabihf/7.4.0/../../../../arm-buildroot-linux-musleabihf/bin/ld: ./.libs/libmini.a(libmini_la-mini-exceptions.o): in function `build_stack_trace': +/home/buildroot/autobuild/run/instance-1/output/build/mono-5.20.1.27/mono/mini/mini-exceptions.c:365: undefined reference to `_Unwind_GetIP' +collect2: error: ld returned 1 exit status + +Fixes: + - http://autobuild.buildroot.net/results/dbd64c89815d393a4e28b312d74fd80ee6de92da + +Signed-off-by: Fabrice Fontaine <fontaine.fabrice@gmail.com> +--- + configure.ac | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/configure.ac b/configure.ac +index d724f9e2d27..c3067246f08 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -2206,6 +2206,11 @@ if test x$host_win32 = xno; then + dnl ***************************** + AC_CHECK_LIB(socket, socket, LIBS="$LIBS -lsocket") + ++ dnl ***************************** ++ dnl *** Checks for libunwind *** ++ dnl **************************** ++ AC_CHECK_LIB(unwind, _Unwind_GetIP, LIBS="$LIBS -lunwind") ++ + case "$host" in + *-*-*freebsd*) + dnl ***************************** +-- +2.20.1 + diff --git a/package/mono/mono.mk b/package/mono/mono.mk index bb482a6d5f..53589f4071 100644 --- a/package/mono/mono.mk +++ b/package/mono/mono.mk @@ -40,7 +40,9 @@ ifeq ($(BR2_PACKAGE_LIBICONV),y) MONO_DEPENDENCIES += libiconv endif -MONO_DEPENDENCIES += host-mono +MONO_DEPENDENCIES += \ + host-mono \ + $(if $(BR2_PACKAGE_LIBUNWIND),libunwind) ## Mono managed
Add libunwind dependency as well as a patch to link with it Fixes: - http://autobuild.buildroot.net/results/dbd64c89815d393a4e28b312d74fd80ee6de92da Signed-off-by: Fabrice Fontaine <fontaine.fabrice@gmail.com> --- ...03-configure.ac-checks-for-libunwind.patch | 40 +++++++++++++++++++ package/mono/mono.mk | 4 +- 2 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 package/mono/0003-configure.ac-checks-for-libunwind.patch