Mingw-packages: any ld.exe from binutils > v2.30 is broken

Created on 6 Jan 2020  路  21Comments  路  Source: msys2/MINGW-packages

Hello,
I found that any ld.exe from binutils > v2.30 is broken and returns ld returned 5 exit status error code. So I have tried to download mingw-w64-i686-binutils-2.30-6-any.pkg.tar.xz from msys2 repo http://repo.msys2.org and replaced the installed ld.exe with the downloaded one, this times it compiled and linked without problems.

My code is very big to share it so you can reproduce it yourself. My code requires at least wxWidgets v3.1.3 to build.

What can I do make you believe that any version > v2.30 is really broken!? Because it is working without problems for small projects and makes you believe it is working properly.

Thank you in advance.

needinfo

All 21 comments

You need to provide a recipe to reproduce the problem based on publicly available resources. It is very important that the recipe is as simple as possible. See for example this for some good advice.

ld is being used to build large projects (Clang/LLVM, Qt, ...). Actually, is being used to build almost everything on the MSYS2/MinGW-w64 repositories, so it is not "broken", it just contains a bug that affects your project (supposing that your diagnostic is correct).

By saying broken I meant buggy of course.
I will edit my project to make it compile the wxWidgets v3.0.4 that comes with Mingw-w64 and make it as minimal as possible then upload it.

binutils has been updated, maybe give the new version a try.

Thank you for the info, I will give it a try.

KeePassXC is experiencing this same problem with binutils 2.34. Just downgraded to 2.33 and the problem went away immediately. To reproduce simply checkout our repository (develop branch) and build keepassxc-proxy (make keepassxc-proxy) in release mode.

https://github.com/keepassxreboot/keepassxc

I narrowed down the fault to the combination of linker parameters: -Wl,--nxcompat -Wl,--dynamicbase -Wl,--high-entropy-va. When these parameters are removed the fault goes away using v2.34.

@droidmonkey I experienced the same linker error for some but not all keepassx unit tests.
It seems that ASLR (-Wl,--dynamicbase) causes this error, adding -Wl,--export-all-symbols fixed the problem for me.

A recent fresh install of MSYS2 did not exhibit these problems, I think this can be closed.

For me its still a problem without the additional linker flag mentioned above.
With binutils v2.30 it works flawless, binutils v2.34 results in ld returned 5 exit status.
Probably the behaviour of ld has changed...

I have the same problem.

v2.35 still have the problem

@droidmonkey I experienced the same linker error for some but not all keepassx unit tests.
It seems that ASLR (-Wl,--dynamicbase) causes this error, adding -Wl,--export-all-symbols fixed the problem for me.

That's very odd. There was a change in binutils 2.34 which should have made -Wl,--dynamicbase actually work correctly for executables. -Wl,--export-all-symbols sort of sounds like it would work around the issue that was solved in 2.34.

I recently authored a patch against binutils upstream to make dynamicbase, nxcompat, and high-entropy-va (on x64) the default, and this project is currently in the process of enabling those flags and testing for breakage in packages. Hopefully this will help suss out any issues with them. Whatever is going on in this issue (and it may be several different things that just happen to result in ld failing with error code 5), sounds like an issue in binutils upstream and not in the packaging of binutils here.

There was just a discussion on gitter which revealed that upstream cmake attempts to create executables with -Wl,--out-implib and that that is failing now with --enable-reloc-section enabled, which is now enabled by default, and was enabled with -Wl,--dynamicbase as of 2.34 IIRC. And -Wl,--export-all-symbols does work around it.

So it sounds like attempting to create an import library while linking an executable with a relocation section but no exported symbols fails with exit code 5.

Hey @jeremyd2019 The patch to cmake predates adding this switch so this has been an issue forever AFAIR! I'll add a link to your comment to my PR later though anyway.

Pasting my comment from CMake pull request:

I've tested this a bit with different toolchains: gcc/clang+lld (mingw-w64), cl+link (MSVC), clang-cl+link (MSVC), clang-cl+lld-link (MSVC) will all ignore import library option when creating executable without even a warning.

ld.bfd on the other hand segfaults when emitting reloc section is enabled (this recently became default in the upstream).

Backtrace is not useful since all debug info has been stripped:

(lldb) r
Process 6844 launched: 'D:\msys64\mingw64\bin\ld.exe' (x86_64)
Process 6844 stopped
* thread #1, stop reason = Exception 0xc0000005 encountered at address 0x7ffb64fbd2f1: Access violation reading location
 0x00000000
    frame #0: 0x00007ffb64fbd2f1 msvcrt.dll`strlen + 49
msvcrt.dll`strlen:
->  0x7ffb64fbd2f1 <+49>: movq   (%rax), %rdx
    0x7ffb64fbd2f4 <+52>: movq   %r8, %r9
    0x7ffb64fbd2f7 <+55>: addq   $0x8, %rax
    0x7ffb64fbd2fb <+59>: addq   %rdx, %r9
(lldb) bt
* thread #1, stop reason = Exception 0xc0000005 encountered at address 0x7ffb64fbd2f1: Access violation reading location
 0x00000000
  * frame #0: 0x00007ffb64fbd2f1 msvcrt.dll`strlen + 49
    frame #1: 0x00000000004f3dff ld.exe
    frame #2: 0x000000000042d4d3 ld.exe
    frame #3: 0x000000000042329e ld.exe
    frame #4: 0x0000000000414d0d ld.exe
    frame #5: 0x0000000000533f0b ld.exe
    frame #6: 0x00000000004013c1 ld.exe
    frame #7: 0x00000000004014f6 ld.exe
    frame #8: 0x00007ffb64da6fd4 kernel32.dll`BaseThreadInitThunk + 20
    frame #9: 0x00007ffb665dcec1 ntdll.dll`RtlUserThreadStart + 33

Interesting. Might want to report that to binutils bugzilla. I'm going to try to get a symbolicated backtrace at least, maybe I can find a simple patch for it.

STACK_TEXT:  
0000003c`5dbff948 00007ff6`f8aa4907 : 00000000`00000000 00000001`40023760 0000003c`5dbff9ec 00000000`00000044 : msvcrt!strlen+0x31
0000003c`5dbff950 00007ff6`f898f53b : 00000000`00000000 00007ff6`f897618a 0000003c`5dbff9f0 00007ff6`f89680f0 : ld!xstrdup+0x17
0000003c`5dbff990 00007ff6`f8980a08 : 000001a9`af6758a0 000001a9`ad6d88b0 00007ff6`f8c618c0 00007ff6`f89680f0 : ld!pep_dll_generate_implib+0x53
0000003c`5dbffa60 00007ff6`f8975c27 : 0000003c`5dbffabc 0000000a`af68bd50 00000000`00000025 00000001`00000044 : ld!gld_i386pep_finish+0xb1
0000003c`5dbffaa0 00007ff6`f896ab7d : 00000000`00000004 00007ff6`00000001 00000000`00000000 00007ff6`f8976050 : ld!ldemul_finish+0x15
0000003c`5dbffad0 00007ff6`f896f22e : 00007ff6`f8b14608 00007ff6`f8b067c0 000001a9`00000001 00007ffc`50000061 : ld!lang_process+0x6c6
0000003c`5dbffb90 00007ff6`f89513c1 : 00000000`00000025 000001a9`ad6d1b40 00007ff6`f8c67398 00000000`00000000 : ld!main+0x795
0000003c`5dbffc60 00007ff6`f89514f6 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ld!__tmainCRTStartup+0x231
0000003c`5dbffd30 00007ffc`a86b6fd4 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ld!mainCRTStartup+0x16
0000003c`5dbffd60 00007ffc`a9b1cec1 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : KERNEL32!BaseThreadInitThunk+0x14
0000003c`5dbffd90 00000000`00000000 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ntdll!RtlUserThreadStart+0x21

@jeremyd2019 should we patch this downstream for now?

Just wondering. As we are importing many patches from upstream, how about using a git commit as source tarball for binutils?

@jeremyd2019 should we patch this downstream for now?

I was wondering the same thing. Was trying to have a little patience for upstream to get to the bug. If you like I can make another PR.

Just wondering. As we are importing many patches from upstream, how about using a git commit as source tarball for binutils?

Are you talking about an upstream git commit, with whatever other changes might be pending for 2.36, or a branch on a fork with the desired patches cherry-picked on top of 2.35?

I wish gcc/ld gave a better indication of a crash than 'exited with code 5'. When ld was run directly rather than through gcc I saw "Segmentation fault" printed, but I could not figure out how to get it to trigger the Windows JIT debugger. Something must be catching the exception and printing "Segmentation fault", but I couldn't find it (keeping in mind this is mingw not msys/cygwin, where there's error_start).

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Alex-Gamper picture Alex-Gamper  路  8Comments

fspeech picture fspeech  路  6Comments

gbschenkel picture gbschenkel  路  5Comments

WilliamKappler picture WilliamKappler  路  4Comments

WuZhengqiang666 picture WuZhengqiang666  路  3Comments