[GHC] #8935: Obscure linker bug leads to crash in GHCi
GHC
ghc-devs at haskell.org
Tue Apr 29 21:44:37 UTC 2014
#8935: Obscure linker bug leads to crash in GHCi
-------------------------------------+------------------------------------
Reporter: simonmar | Owner: simonmar
Type: bug | Status: new
Priority: high | Milestone: 7.8.3
Component: Runtime System | Version: 7.8.1-rc2
Resolution: | Keywords:
Operating System: Unknown/Multiple | Architecture: Unknown/Multiple
Type of failure: GHCi crash | Difficulty: Rocket Science
Test Case: | Blocked By:
Blocking: | Related Tickets:
-------------------------------------+------------------------------------
Comment (by dagit):
I just realized my previous reply probably leaves people wondering: Since
libpthread also DOES NOT define environ why does it give the right
address?
The difference is that libpthread depends on ld-linux.so as a shared
object dependency (grep the readelf -Wa output for `NEEDED`) and ld-
linux.so defines a `LOCAL` symbol for environ. As I understand it, that
means the dynamic linker thinks libpthread defines environ as `LOCAL` (so
it goes to look for a different definition and ends up with the right
one). For libgmp it looks in libc.so and finds a `WEAK` definition and
uses it because there is no other `GLOBAL` definition.
To help demonstrate this, consider this example. On my system, libz.so has
dependencies similar to libgmp.so:
{{{
$ readelf -Wa /usr/lib64/libgmp.so.10 | grep NEEDED
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
$ readelf -Wa /usr/lib64/libz.so.1 | grep NEEDED
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
}}}
And look at this:
{{{
$ ./check-environ /usr/lib64/libgmp.so /usr/lib64/libz.so.1
environ = 0x601058
dlsym(deflt, "environ") = 0x601058
dlsym("libgmp", "environ") = 0x31e45bd508
dlsym("libpthread", "environ") = 0x31e45bd508
}}}
I'm still fuzzy on some of the details, but it seems that `WEAK` and
`LOCAL` mean very different things to the dynamic linker. `WEAK` is the
same as `GLOBAL` but the link priority is lower, while `LOCAL` means the
symbol should not be exported. As far as I can tell, when it finds `LOCAL`
it continues the search whereas with `WEAK` it stops earlier because
technically it has found an exported symbol.
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/8935#comment:6>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list