[GHC] #8935: Obscure linker bug leads to crash in GHCi

GHC ghc-devs at haskell.org
Thu May 1 08:19:39 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 trommler):

 Replying to [comment:6 dagit]:
 > 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]
 > }}}
 >
 >

 > 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.
 I checked on openSUSE 13.1 (x86_64 and powerpc64) and I have the same
 {{{NEEDED}}} for libc.so.

 {{{environ}}} is a {{{WEAK}}} symbol in my libc.so, too.

 Here is my libc.so.6 on powerpc64:
 {{{
 00000000001d7ce0  0000056600000026 R_PPC64_ADDR64         00000000001da1f0
 __environ + 0
 00000000001d7d00  0000056600000026 R_PPC64_ADDR64         00000000001da1f0
 __environ + 0
 00000000001d7ee8  0000056600000026 R_PPC64_ADDR64         00000000001da1f0
 __environ + 0
 00000000001d7ef0  0000056600000026 R_PPC64_ADDR64         00000000001da1f0
 __environ + 0
 00000000001d8018  0000056600000026 R_PPC64_ADDR64         00000000001da1f0
 __environ + 0
 00000000001d84a0  0000056600000026 R_PPC64_ADDR64         00000000001da1f0
 __environ + 0
 00000000001d84a8  0000056600000026 R_PPC64_ADDR64         00000000001da1f0
 __environ + 0
 00000000001d84b0  0000056600000026 R_PPC64_ADDR64         00000000001da1f0
 __environ + 0
 00000000001d8570  0000056600000026 R_PPC64_ADDR64         00000000001da1f0
 __environ + 0
 00000000001d8928  0000056600000026 R_PPC64_ADDR64         00000000001da1f0
 __environ + 0
 00000000001d81e8  0000013100000026 R_PPC64_ADDR64         00000000001da1f0
 _environ + 0
    305: 00000000001da1f0     8 OBJECT  WEAK   DEFAULT   32
 _environ@@GLIBC_2.3
   1026: 00000000001da1f0     8 OBJECT  WEAK   DEFAULT   32
 environ@@GLIBC_2.3
   1382: 00000000001da1f0     8 OBJECT  GLOBAL DEFAULT   32
 __environ@@GLIBC_2.3
    178: 00000000001d8fa8     8 OBJECT  LOCAL  DEFAULT   32 last_environ
   2904: 00000000001c9628  1436 FUNC    LOCAL  DEFAULT   28
 __add_to_environ
   4138: 00000000001da1f0     8 OBJECT  WEAK   DEFAULT   32 _environ
   4843: 00000000001da1f0     8 OBJECT  GLOBAL DEFAULT   32 __environ
   4957: 00000000001da1f0     8 OBJECT  WEAK   DEFAULT   32 environ
 }}}

 On x86_64 it looks similar to comment [comment:5] except the line with
 environ.c is missing.

 Do openSUSE patch their system linker? I'll go ask on their mailing list
 and report back.

--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/8935#comment:10>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler


More information about the ghc-tickets mailing list