[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