Bug 77459 - [6 Regression] undefined reference to `snprintf' when building mingw-w64 cross-compiler
Summary: [6 Regression] undefined reference to `snprintf' when building mingw-w64 cros...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: libstdc++ (show other bugs)
Version: 6.2.0
: P3 normal
Target Milestone: 6.3
Assignee: François Dumont
URL:
Keywords: build
Depends on:
Blocks:
 
Reported: 2016-09-02 18:08 UTC by Georg Koppen
Modified: 2016-12-08 12:42 UTC (History)
4 users (show)

See Also:
Host:
Target: mingw-w64
Build:
Known to work:
Known to fail:
Last reconfirmed: 2016-12-08 00:00:00


Attachments
Stop using __builtin_snprintf until __has_builtin is supported. (492 bytes, patch)
2016-11-07 21:31 UTC, François Dumont
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Georg Koppen 2016-09-02 18:08:48 UTC
When switching GCC to 6.2.0 I get the following compiler error while trying to build the mingw-w64 cross-compiler:

    /bin/bash ../libtool --tag CXX   --mode=link /home/ubuntu/build/gcc/./gcc/xgcc -shared-libgcc -B/home/ubuntu/build/gcc/./gcc -nostdinc++ -L/home/ubuntu/build/gcc/i686-w64-mingw32/libstdc++-v3/src -L/home/ubuntu/build/gcc/i686-w64-mingw32/libstdc++-v3/src/.libs -L/home/ubuntu/build/gcc/i686-w64-mingw32/libstdc++-v3/libsupc++/.libs -L/home/ubuntu/install/mingw-w64/i686-w64-mingw32/lib -L/home/ubuntu/install/mingw-w64/mingw/lib -isystem /home/ubuntu/install/mingw-w64/i686-w64-mingw32/include -isystem /home/ubuntu/install/mingw-w64/mingw/include -B/home/ubuntu/install/mingw-w64/i686-w64-mingw32/bin/ -B/home/ubuntu/install/mingw-w64/i686-w64-mingw32/lib/ -isystem /home/ubuntu/install/mingw-w64/i686-w64-mingw32/include -isystem /home/ubuntu/install/mingw-w64/i686-w64-mingw32/sys-include     -Wl,-O1  -no-undefined -bindir "/home/ubuntu/install/mingw-w64/i686-w64-mingw32/lib/../lib" -Wl,--gc-sections  -std=gnu++98 -DDLL_EXPORT -DPIC -fno-implicit-templates  -Wall -Wextra -Wwrite-strings -Wcast-qual -Wabi  -fdiagnostics-show-location=once   -ffunction-sections -fdata-sections  -frandom-seed=libstdc++.la  -o libstdc++.la -version-info 6:22:0 -Wl,--version-script=libstdc++-symbols.ver -lm -rpath /home/ubuntu/install/mingw-w64/i686-w64-mingw32/lib/../lib compatibility.lo compatibility-debug_list.lo compatibility-debug_list-2.lo  compatibility-c++0x.lo compatibility-atomic-c++0x.lo compatibility-thread-c++0x.lo compatibility-chrono.lo compatibility-condvar.lo  ../libsupc++/libsupc++convenience.la ../src/c++98/libc++98convenience.la ../src/c++11/libc++11convenience.la
    libtool: link:  /home/ubuntu/build/gcc/./gcc/xgcc -shared-libgcc -B/home/ubuntu/build/gcc/./gcc -nostdinc++ -L/home/ubuntu/build/gcc/i686-w64-mingw32/libstdc++-v3/src -L/home/ubuntu/build/gcc/i686-w64-mingw32/libstdc++-v3/src/.libs -L/home/ubuntu/build/gcc/i686-w64-mingw32/libstdc++-v3/libsupc++/.libs -L/home/ubuntu/install/mingw-w64/i686-w64-mingw32/lib -L/home/ubuntu/install/mingw-w64/mingw/lib -isystem /home/ubuntu/install/mingw-w64/i686-w64-mingw32/include -isystem /home/ubuntu/install/mingw-w64/mingw/include -B/home/ubuntu/install/mingw-w64/i686-w64-mingw32/bin/ -B/home/ubuntu/install/mingw-w64/i686-w64-mingw32/lib/ -isystem /home/ubuntu/install/mingw-w64/i686-w64-mingw32/include -isystem /home/ubuntu/install/mingw-w64/i686-w64-mingw32/sys-include    -shared -nostdlib /home/ubuntu/install/mingw-w64/i686-w64-mingw32/lib/dllcrt2.o /home/ubuntu/build/gcc/./gcc/crtbegin.o  .libs/compatibility.o .libs/compatibility-debug_list.o .libs/compatibility-debug_list-2.o .libs/compatibility-c++0x.o .libs/compatibility-atomic-c++0x.o .libs/compatibility-thread-c++0x.o .libs/compatibility-chrono.o .libs/compatibility-condvar.o  -Wl,--whole-archive ../libsupc++/.libs/libsupc++convenience.a ../src/c++98/.libs/libc++98convenience.a ../src/c++11/.libs/libc++11convenience.a -Wl,--no-whole-archive  -L/home/ubuntu/build/gcc/i686-w64-mingw32/libstdc++-v3/libsupc++/.libs -L/home/ubuntu/build/gcc/i686-w64-mingw32/libstdc++-v3/src -L/home/ubuntu/build/gcc/i686-w64-mingw32/libstdc++-v3/src/.libs -L/home/ubuntu/install/mingw-w64/i686-w64-mingw32/lib -L/home/ubuntu/install/mingw-w64/mingw/lib -L/home/ubuntu/build/gcc/./gcc -L/home/ubuntu/install/mingw-w64/i686-w64-mingw32/bin -lmingw32 -lgcc_s -lgcc -lmoldname -lmingwex -lmsvcr100 -ladvapi32 -lshell32 -luser32 -lkernel32 -lmingw32 -lgcc_s -lgcc -lmoldname -lmingwex -lmsvcr100 /home/ubuntu/build/gcc/./gcc/crtend.o  -Wl,-O1 -Wl,--gc-sections -Wl,--version-script=libstdc++-symbols.ver   -o .libs/libstdc++-6.dll -Wl,--enable-auto-image-base -Xlinker --out-implib -Xlinker .libs/libstdc++.dll.a
    ../src/c++11/.libs/libc++11convenience.a(debug.o): In function `format_word<char const*>':
    /home/ubuntu/build/gcc/i686-w64-mingw32/libstdc++-v3/src/c++11/../../../../gcc-6.2.0/libstdc++-v3/src/c++11/debug.cc:535: undefined reference to `snprintf'
    /home/ubuntu/build/gcc/i686-w64-mingw32/libstdc++-v3/src/c++11/../../../../gcc-6.2.0/libstdc++-v3/src/c++11/debug.cc:535: undefined reference to `snprintf'
    /home/ubuntu/build/gcc/i686-w64-mingw32/libstdc++-v3/src/c++11/../../../../gcc-6.2.0/libstdc++-v3/src/c++11/debug.cc:535: undefined reference to `snprintf'
    collect2: error: ld returned 1 exit status 

Using GCC 5.1.0 works as expected.
Comment 1 Georg Koppen 2016-09-27 12:22:01 UTC
FWIW: backing out r227885 (and r227888) "fixes" this problem for me.
Comment 2 Jonathan Wakely 2016-09-27 12:55:13 UTC
It's 2016, how can snprintf not be supported still?
Comment 3 Georg Koppen 2016-09-27 13:06:56 UTC
(In reply to Jonathan Wakely from comment #2)
> It's 2016, how can snprintf not be supported still?

I asked about that problem in #mingw-w64 a while ago and got the following answer:

M$ does not provide `snprintf()` despite their non-standard extension `_snprintf()`. With mingw-w64, if the macro `__USE_MINGW_ANSI_STDIO` is defined to `1`, `snprintf` is a macro that redirects calls to `snprintf` to `__mingw_snprintf` instead.

Not sure if that helps debugging/fixing.
Comment 4 Jonathan Wakely 2016-09-27 13:12:19 UTC
Does this help?


--- a/libstdc++-v3/src/c++11/debug.cc
+++ b/libstdc++-v3/src/c++11/debug.cc
@@ -540,10 +540,25 @@ namespace
   using _Error_formatter = __gnu_debug::_Error_formatter;
   using _Parameter = __gnu_debug::_Error_formatter::_Parameter;
 
+#ifdef _GLIBCXX_USE_C99_STDIO
   template<typename _Tp>
     int
     format_word(char* buf, int n, const char* fmt, _Tp s)
     { return std::min(__builtin_snprintf(buf, n, fmt, s), n - 1); }
+#else
+    int
+    format_word(char* buf, int n, const char* fmt, const char* s)
+    {
+      if ((int)__builtin_strlen(s) >= n)
+       s = "???";
+      return std::min(__builtin_sprintf(buf, fmt, s), n - 1);
+    }
+
+  template<typename _Tp>
+    int
+    format_word(char* buf, int n, const char* fmt, _Tp s)
+    { return std::min(__builtin_sprintf(buf, fmt, s), n - 1); }
+#endif
 
   void
   get_max_length(std::size_t& max_length)
Comment 5 Georg Koppen 2016-09-29 07:35:05 UTC
No, it is still broken after applying the patch to 6.2.0:

../src/c++11/.libs/libc++11convenience.a(debug.o): In function `format_word<char const*>':
/home/ubuntu/build/gcc/i686-w64-mingw32/libstdc++-v3/src/c++11/../../../../gcc-6.2.0/libstdc++-v3/src/c++11/debug.cc:536: undefined reference to `snprintf'
/home/ubuntu/build/gcc/i686-w64-mingw32/libstdc++-v3/src/c++11/../../../../gcc-6.2.0/libstdc++-v3/src/c++11/debug.cc:536: undefined reference to `snprintf'
/home/ubuntu/build/gcc/i686-w64-mingw32/libstdc++-v3/src/c++11/../../../../gcc-6.2.0/libstdc++-v3/src/c++11/debug.cc:536: undefined reference to `snprintf'
collect2: error: ld returned 1 exit status
Comment 6 François Dumont 2016-11-07 21:31:12 UTC
Created attachment 39984 [details]
Stop using __builtin_snprintf until __has_builtin is supported.

Could you try this patch ? Until we have __has_builtin support I propose to simulate __builtin_snprintf with __builtin_sprint.
Comment 7 Jonathan Wakely 2016-11-07 22:05:37 UTC
(In reply to François Dumont from comment #6)
> Created attachment 39984 [details]
> Stop using __builtin_snprintf until __has_builtin is supported.
> 
> Could you try this patch ? Until we have __has_builtin support I propose to
> simulate __builtin_snprintf with __builtin_sprint.

This patch is wrong in several ways. GCC always supports __builtin_snprintf, so even if we supported __has_builtin (which is "if" not "until") the test would not be right. What happens when it's not supported by the target is a linker error, not a missing builtin.

The patch adds complexity and pessimizes targets that do support snprintf.
Comment 8 François Dumont 2016-11-08 21:35:08 UTC
Ok, at least it confirms what I thought about builtins. So the problem is rather a buggy target.

Even if so I'll try to find an alternative approach to avoid snprintf usage.
Comment 9 François Dumont 2016-11-10 21:34:21 UTC
Fix with rev 242055 which simply remove format_word method.
Comment 10 Jakub Jelinek 2016-11-25 21:41:25 UTC
Assuming r242055 fixed it then.
Comment 11 Georg Koppen 2016-11-28 13:35:01 UTC
(In reply to Jakub Jelinek from comment #10)
> Assuming r242055 fixed it then.

Yes, that issue is not showing up anymore when compiling with r242055.
Comment 12 Jonathan Wakely 2016-12-08 10:31:55 UTC
I'm backporting this to gcc-6-branch too.
Comment 13 Jonathan Wakely 2016-12-08 12:41:30 UTC
Author: redi
Date: Thu Dec  8 12:40:58 2016
New Revision: 243435

URL: https://gcc.gnu.org/viewcvs?rev=243435&root=gcc&view=rev
Log:
PR77459 avoid snprintf for debug mode diagnostics

Backport from mainline
2016-11-10  François Dumont  <fdumont@gcc.gnu.org>

        PR libstdc++/77459
	* src/c++11/debug.cc (format_word): Delete.
	(print_literal): New. Replace call to print_word for literals.

Modified:
    branches/gcc-6-branch/libstdc++-v3/ChangeLog
    branches/gcc-6-branch/libstdc++-v3/src/c++11/debug.cc
Comment 14 Jonathan Wakely 2016-12-08 12:42:35 UTC
Fixed for 6.3