Bug 236165

Summary: crash in malloc with ld.lld and -Wl,--export-dynamic -static
Product: Base System Reporter: Andrew "RhodiumToad" Gierth <andrew>
Component: binAssignee: freebsd-toolchain (Nobody) <toolchain>
Status: Open ---    
Severity: Affects Some People CC: arichardson, emacsray, emaste, freebsd, kevans, toolchain
Priority: --- Keywords: crash, needs-patch, needs-qa
Version: 12.0-STABLEFlags: koobs: mfc-stable13?
koobs: mfc-stable12?
koobs: mfc-stable11-
Hardware: Any   
OS: Any   
URL: https://reviews.llvm.org/D42748
Bug Depends on:    
Bug Blocks: 231882    

Description Andrew "RhodiumToad" Gierth 2019-03-02 18:58:42 UTC
The combination of -Wl,--export-dynamic and -static is used by some Autoconf tests ("checking whether a statically linked program can dlopen itself"). This consistently drops a core on 12-stable (tested at r344237) but apparently not on 11-stable. Tested on amd64 and armv7.

dlopen is not actually implicated in the issue: it can be reproduced with only this:

#include <stdlib.h>
int main()
{
  malloc(1);
  return 0;
}

cc -g -Wl,--export-dynamic -static testprog.c
./a.out
segmentation fault (core dumped)  ./a.out

The problem seems to be that the a.out is actually dynamic in spite of the -static option, but it still has libc.a statically linked into it. With ld.bfd, the a.out comes out as static and there is no coredump.

I doubt this is breaking any real code, but it generates a lot of worrying logfile entries when building ports.
Comment 1 Kyle Evans freebsd_committer freebsd_triage 2019-03-02 19:03:27 UTC
Kicking it over to -toolchain@
Comment 2 Alex Richardson freebsd_committer freebsd_triage 2019-03-02 21:48:06 UTC
We also ran into this problem in CheriBSD. The binary is actually static (but file will report it as dynamically linked). However, it has a PT_DYNAMIC header and the symbol _DYNAMIC does not resolve to zero. This causes these crashes because there are various checks in libc, csu code, etc. that assume that `if (&_DYNAMIC == NULL)` is true the binary is statically linked and otherwise it assumes we are running a dynamic binary.
For our CHERI compilers I just modified ld.lld to not emit _DYNAMIC and the PT_DYNAMIC header. I also attempted to upstream this fix but haven't got around to committing it since I'm not 100% sure what the correct behaviour is.

See also https://reviews.llvm.org/D42748
Comment 3 maskray 2019-05-21 13:11:46 UTC
Replied in https://reviews.llvm.org/D42748#1510087 :)

moving away from &_DYNAMIC will be a more reliable approach.
To check if an executable is dynamically linked, inspecting PT_INTERP is a better choice.
Comment 4 Ed Maste freebsd_committer freebsd_triage 2019-08-19 13:21:20 UTC
IMO this needs to be addressed in lld. Discussion is happening in LLVM review D42748.
Comment 5 maskray 2019-08-20 16:18:57 UTC
(In reply to Ed Maste from comment #4)

Commented at https://reviews.llvm.org/D42748#1637598

I think libc should probably be changed. That will also benefit future static PIE work.
Comment 6 Kubilay Kocak freebsd_committer freebsd_triage 2021-07-29 02:26:02 UTC
^Triage: Correct review url (s/freebsd/llvm) and move to URL (see also only takes freebsd review urls)
Comment 7 Ed Maste freebsd_committer freebsd_triage 2021-07-29 15:16:08 UTC
Correct URL reference (reviews.llvm.org, not reviews.freebsd.org)