[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