Opened 3 years ago

Closed 2 years ago

#7062 closed bug (fixed)

Spurious undefined reference to `openpty'

Reported by: simonmar Owned by:
Priority: high Milestone: 7.6.2
Component: Compiler Version: 7.4.2
Keywords: Cc: ivan.perez@…, ptrommler@…
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: None/Unknown Test Case:
Blocked By: Blocking:
Related Tickets: Differential Revisions:

Description

I'm seeing these since upgrading our build machines from Ubuntu 10.04 to 12.04:

=====> process001(dyn) 3159 of 3394 [0, 96, 0]
cd ../../libraries/process/tests && '/64playpen/simonmar/nightly/HEAD-cam-04-unx/x86_64-unknown-linux/inplace/bin/ghc-stage2' -fforce-recomp -dcore-lint -dcmm-lint -dno-debug-output -no-user-package-db -rtsopts  -fno-ghci-history -o process001 process001.hs -O -dynamic   >process001.comp.stderr 2>&1
Compile failed (status 256) errors were:
[1 of 1] Compiling Main             ( process001.hs, process001.o )
Linking process001 ...
/64playpen/simonmar/nightly/HEAD-cam-04-unx/x86_64-unknown-linux/libraries/unix/dist-install/build/libHSunix-2.5.1.0-ghc7.5.20120706.so: undefined reference to `openpty'
collect2: ld returned 1 exit status

*** unexpected failure for process001(dyn)

I'm stumped. Here's what I've discovered so far:

  • It only happens with -dynamic
  • The openpty symbol comes from the util library, which we are correctly linking in. The libutil.so library is present, and I've checked that we're getting the right one.
  • It only happens when using the process package, which depends on unix. Using unix by itself is fine. So something about the process package is messing up the linker.
  • I've tried removing all the -L options and linking libraries by full pathname, just in case we're picking up something from the wrong place; that doesn't help.

Attachments (3)

0001-Add-missing-flag-for-respecting-EXTRA_LIBDIR.patch (998 bytes) - added by pgj 3 years ago.
0002-Do-not-add-RUNPATH-tag.patch (1.7 KB) - added by trommler 3 years ago.
Added comment to patch
0001-Set-LD_LIBRARY_PATH-on-Linux.patch (3.0 KB) - added by trommler 2 years ago.
Updated patch

Download all attachments as: .zip

Change History (32)

comment:1 Changed 3 years ago by nus

$ ls -l /usr/bin/ld
lrwxrwxrwx 1 root root 6 Mar  9 03:10 /usr/bin/ld -> ld.bfd

$ ~/dev/ghcbld/inplace/bin/ghc-stage2 -o process001 process001.hs -dynamic -optl -Wl,-yopenpty
Linking process001 ...
/home/user/dev/ghcbld/libraries/unix/dist-install/build/libHSunix-2.5.1.0-ghc7.5.so: reference to openpty
/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/libutil.so: definition of openpty
/home/user/dev/ghcbld/libraries/unix/dist-install/build/libHSunix-2.5.1.0-ghc7.5.so: reference to openpty
/home/user/dev/ghcbld/libraries/unix/dist-install/build/libHSunix-2.5.1.0-ghc7.5.so: undefined reference to `openpty'
collect2: ld returned 1 exit status

After making /usr/bin/ld point to ld.gold and editing lib/settings to exclude incompatible options:

user@host:~/dev/ghcbld/libraries/process/tests
$ ~/ghcbld/inplace/bin/ghc-stage2 -o process001 process001.hs -dynamic -optl -Wl,-yopenpty
Linking process001 ...
/home/user/ghcbld/libraries/unix/dist-install/build/libHSunix-2.5.1.0-ghc7.5.so: reference to openpty
/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/libutil.so: definition of openpty

Seems like ld.bfd bug.

comment:2 Changed 3 years ago by ivan.perez

  • Cc ivan.perez@… added

I just hit this bug. I case it can help, here's my bit.

I wrote a library that depends on process. When I install the library, no errors are reported.

I have a program to test my library in ./BoardMain.hs. The library modules are located in ../../src/.

If I install the library and compile the program with -dynamic, I get:

$ ghc -Wall --make BoardMain.hs  -dynamic 2>&1 > /dev/null
/usr/lib/ghc/unix-2.5.1.0/libHSunix-2.5.1.0-ghc7.4.1.so: undefined reference to `openpty'
collect2: ld returned 1 exit status

Using -dynamic and adding the library modules directly to the import path instead of using my library as a package, I get:

$ ghc -Wall --make BoardMain.hs -i../../src:. -dynamic 2>&1 > /dev/null
$ ls -sh BoardMain
188K BoardMain

comment:3 Changed 3 years ago by nus

All right, "It's not a bug, it's a feature".

The linking command issued by 'inplace/bin/ghc-stage2 -o process001 process001.hs -dynamic' through gcc (reformatted for clarity):

/usr/lib/gcc/x86_64-linux-gnu/4.6/collect2
--sysroot=/ --build-id --no-add-needed --as-needed --eh-frame-hdr -m elf_x86_64
--hash-style=gnu -dynamic-linker /lib64/ld-linux-x86-64.so.2 -z relro
-o process001
-u ghczmprim_GHCziTypes_Izh_static_info -u ghczmprim_GHCziTypes_Czh_static_info -u ghczmprim_GHCziTypes_Fzh_static_info -u ghczmprim_GHCziTypes_Dzh_static_info -u base_GHCziPtr_Ptr_static_info -u ghczmprim_GHCziTypes_Wzh_static_info -u base_GHCziInt_I8zh_static_info -u base_GHCziInt_I16zh_static_info -u base_GHCziInt_I32zh_static_info -u base_GHCziInt_I64zh_static_info -u base_GHCziWord_W8zh_static_info -u base_GHCziWord_W16zh_static_info -u base_GHCziWord_W32zh_static_info -u base_GHCziWord_W64zh_static_info -u base_GHCziStable_StablePtr_static_info -u ghczmprim_GHCziTypes_Izh_con_info -u ghczmprim_GHCziTypes_Czh_con_info -u ghczmprim_GHCziTypes_Fzh_con_info -u ghczmprim_GHCziTypes_Dzh_con_info -u base_GHCziPtr_Ptr_con_info -u base_GHCziPtr_FunPtr_con_info -u base_GHCziStable_StablePtr_con_info -u ghczmprim_GHCziTypes_False_closure -u ghczmprim_GHCziTypes_True_closure -u base_GHCziPack_unpackCString_closure -u base_GHCziIOziException_stackOverflow_closure -u base_GHCziIOziException_heapOverflow_closure -u base_ControlziExceptionziBase_nonTermination_closure -u base_GHCziIOziException_blockedIndefinitelyOnMVar_closure -u base_GHCziIOziException_blockedIndefinitelyOnSTM_closure -u base_ControlziExceptionziBase_nestedAtomically_closure -u base_GHCziWeak_runFinalizzerBatch_closure -u base_GHCziTopHandler_flushStdHandles_closure -u base_GHCziTopHandler_runIO_closure -u base_GHCziTopHandler_runNonIO_closure -u base_GHCziConcziIO_ensureIOManagerIsRunning_closure -u base_GHCziConcziSync_runSparks_closure
-u base_GHCziConcziSignal_runHandlers_closure
/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crt1.o
/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crti.o
/usr/lib/gcc/x86_64-linux-gnu/4.6/crtbegin.o
-L/home/user/dev/ghcbld/libraries/process/dist-install/build -L/home/user/dev/ghcbld/libraries/directory/dist-install/build -L/home/user/dev/ghcbld/libraries/unix/dist-install/build -L/home/user/dev/ghcbld/libraries/bytestring/dist-install/build -L/home/user/dev/ghcbld/libraries/time/dist-install/build -L/home/user/dev/ghcbld/libraries/old-locale/dist-install/build -L/home/user/dev/ghcbld/libraries/filepath/dist-install/build -L/home/user/dev/ghcbld/libraries/deepseq/dist-install/build -L/home/user/dev/ghcbld/libraries/array/dist-install/build -L/home/user/dev/ghcbld/libraries/base/dist-install/build -L/home/user/dev/ghcbld/libraries/integer-gmp/dist-install/build -L/home/user/dev/ghcbld/libraries/ghc-prim/dist-install/build -L/home/user/dev/ghcbld/rts/dist/build -L/usr/lib/gcc/x86_64-linux-gnu/4.6 -L/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/4.6/../../..
--hash-size=31 --reduce-memory-overheads
process001.o
-rpath /home/user/dev/ghcbld/libraries/process/dist-install/build -rpath /home/user/dev/ghcbld/libraries/directory/dist-install/build -rpath /home/user/dev/ghcbld/libraries/unix/dist-install/build -rpath /home/user/dev/ghcbld/libraries/bytestring/dist-install/build -rpath /home/user/dev/ghcbld/libraries/time/dist-install/build -rpath /home/user/dev/ghcbld/libraries/old-locale/dist-install/build -rpath /home/user/dev/ghcbld/libraries/filepath/dist-install/build -rpath /home/user/dev/ghcbld/libraries/deepseq/dist-install/build -rpath /home/user/dev/ghcbld/libraries/array/dist-install/build -rpath /home/user/dev/ghcbld/libraries/base/dist-install/build -rpath /home/user/dev/ghcbld/libraries/integer-gmp/dist-install/build -rpath /home/user/dev/ghcbld/libraries/ghc-prim/dist-install/build -rpath /home/user/dev/ghcbld/rts/dist/build
/tmp/ghc25888_0/ghc25888_0.o
/tmp/ghc25888_0/ghc25888_1.o
-lHSprocess-1.1.0.0-ghc7.5
-lHSdirectory-1.1.0.1-ghc7.5
-lHSunix-2.5.1.0-ghc7.5
-lrt
-lutil
-ldl
-lpthread
-lHSbytestring-0.10.0.0-ghc7.5
-lHStime-1.4-ghc7.5
-lHSold-locale-1.0.0.4-ghc7.5
-lHSfilepath-1.2.0.1-ghc7.5
-lHSdeepseq-1.2.0.1-ghc7.5
-lHSarray-0.3.0.3-ghc7.5
-lHSbase-4.6.0.0-ghc7.5
-lHSinteger-gmp-0.3.0.0-ghc7.5
-lgmp
-lHSghc-prim-0.2.0.0-ghc7.5
-lHSrts-ghc7.5
-lm
-lrt
-ldl
-lgcc
--as-needed -lgcc_s --no-as-needed
-lc
-lgcc
--as-needed -lgcc_s --no-as-needed
/usr/lib/gcc/x86_64-linux-gnu/4.6/crtend.o
/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crtn.o

From the libraries involved in the linkage only 'HSunix-2.5.1.0-ghc7.5' has references to 'openpty':

$ readelf -a libraries/unix/dist-install/build/libHSunix-2.5.1.0-ghc7.5.so
[...snip...]
Relocation section '.rela.plt' at offset 0x592e8 contains 159 entries:
[...snip...]
0000002b2090  003300000007 R_X86_64_JUMP_SLO 0000000000000000 openpty + 0
[...snip...]
Symbol table '.dynsym' contains 3142 entries:
[...snip...]
    51: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND openpty
[...snip...]
Symbol table '.symtab' contains 6624 entries:
[...snip...]
  3832: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND openpty
[...snip...]
$ readelf -d libraries/process/dist-install/build/libHSprocess-1.1.0.0-ghc7.5.so
Dynamic section at offset 0x16a50 contains 27 entries:
  Tag        Type                         Name/Value
 0x0000000000000001 (NEEDED)             Shared library: [libHSunix-2.5.1.0-ghc7.5.so]
 0x0000000000000001 (NEEDED)             Shared library: [libpthread.so.0]
 0x0000000000000001 (NEEDED)             Shared library: [libHSdeepseq-1.2.0.1-ghc7.5.so]
 0x0000000000000001 (NEEDED)             Shared library: [libHSbase-4.6.0.0-ghc7.5.so]
 0x0000000000000001 (NEEDED)             Shared library: [libHSghc-prim-0.2.0.0-ghc7.5.so]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
 0x000000000000000e (SONAME)             Library soname: [libHSprocess-1.1.0.0-ghc7.5.so]
[...snip...]
$ readelf -d libraries/directory/dist-install/build/libHSdirectory-1.1.0.1-ghc7.5.so
Dynamic section at offset 0x1aa18 contains 30 entries:
  Tag        Type                         Name/Value
 0x0000000000000001 (NEEDED)             Shared library: [libHSunix-2.5.1.0-ghc7.5.so]
 0x0000000000000001 (NEEDED)             Shared library: [libutil.so.1]
 0x0000000000000001 (NEEDED)             Shared library: [libdl.so.2]
 0x0000000000000001 (NEEDED)             Shared library: [libHStime-1.4-ghc7.5.so]
 0x0000000000000001 (NEEDED)             Shared library: [libHSfilepath-1.2.0.1-ghc7.5.so]
 0x0000000000000001 (NEEDED)             Shared library: [libHSbase-4.6.0.0-ghc7.5.so]
 0x0000000000000001 (NEEDED)             Shared library: [libHSinteger-gmp-0.3.0.0-ghc7.5.so]
 0x0000000000000001 (NEEDED)             Shared library: [libHSghc-prim-0.2.0.0-ghc7.5.so]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
 0x000000000000000e (SONAME)             Library soname: [libHSdirectory-1.1.0.1-ghc7.5.so]
[...snip...]
$ readelf -d libraries/unix/dist-install/build/libHSunix-2.5.1.0-ghc7.5.so
Dynamic section at offset 0xb1778 contains 26 entries:
  Tag        Type                         Name/Value
 0x0000000000000001 (NEEDED)             Shared library: [libHSbytestring-0.10.0.0-ghc7.5.so]
 0x0000000000000001 (NEEDED)             Shared library: [libHSbase-4.6.0.0-ghc7.5.so]
 0x0000000000000001 (NEEDED)             Shared library: [libHSinteger-gmp-0.3.0.0-ghc7.5.so]
 0x0000000000000001 (NEEDED)             Shared library: [libHSghc-prim-0.2.0.0-ghc7.5.so]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
 0x000000000000000e (SONAME)             Library soname: [libHSunix-2.5.1.0-ghc7.5.so]
[...snip...]
 --as-needed
 --no-as-needed
This option affects ELF DT_NEEDED tags for dynamic libraries mentioned on the command line after the --as-needed option.  Normally the linker will add a DT_NEEDED tag for each dynamic library mentioned on the command line, regardless of whether the library is actually needed or not.  --as-needed causes a DT_NEEDED tag to only be emitted for a
library that satisfies an undefined symbol reference from a regular object file or, if the library is not found in the DT_NEEDED lists of other libraries linked up to that
point, an undefined symbol reference from another dynamic library.  --no-as-needed restores the default behaviour.

The 'process001' link failure is a consequence of Ubuntu introducing '--as-needed' into the builtin gcc specs:

$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.6/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.6.3-1ubuntu5' --with-bugurl=file:///usr/share/doc/gcc-4.6/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.6 --enable-shared --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.6 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --enable-plugin --enable-objc-gc --disable-werror --with-arch-32=i686 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)
$ gcc -dumpspecs
[...snip...]
*link:
%{!r:--build-id} --no-add-needed --as-needed %{!static:--eh-frame-hdr} %{!m32:-m elf_x86_64} %{m32:-m elf_i386} --hash-style=gnu   %{shared:-shared}   %{!shared:     %{!static:       %{rdynamic:-export-dynamic}       %{m32:-dynamic-linker %{muclibc:/lib/ld-uClibc.so.0;:%{mbionic:/system/bin/linker;:/lib/ld-linux.so.2}}}       %{!m32:-dynamic-linker %{muclibc:/lib/ld64-uClibc.so.0;:%{mbionic:/system/bin/linker64;:/lib64/ld-linux-x86-64.so.2}}}}     %{static:-static}}
[...snip...]

1) If the first '--as-needed' is removed from the above 'collect2' command, the linkage finishes OK:

$ readelf -d process001
Dynamic section at offset 0x2c58 contains 40 entries:
  Tag        Type                         Name/Value
 0x0000000000000001 (NEEDED)             Shared library: [libHSprocess-1.1.0.0-ghc7.5.so]
 0x0000000000000001 (NEEDED)             Shared library: [libHSdirectory-1.1.0.1-ghc7.5.so]
 0x0000000000000001 (NEEDED)             Shared library: [libHSunix-2.5.1.0-ghc7.5.so]
 0x0000000000000001 (NEEDED)             Shared library: [librt.so.1]
 0x0000000000000001 (NEEDED)             Shared library: [libutil.so.1]
 0x0000000000000001 (NEEDED)             Shared library: [libdl.so.2]
 0x0000000000000001 (NEEDED)             Shared library: [libpthread.so.0]
 0x0000000000000001 (NEEDED)             Shared library: [libHSbytestring-0.10.0.0-ghc7.5.so]
 0x0000000000000001 (NEEDED)             Shared library: [libHStime-1.4-ghc7.5.so]
 0x0000000000000001 (NEEDED)             Shared library: [libHSold-locale-1.0.0.4-ghc7.5.so]
 0x0000000000000001 (NEEDED)             Shared library: [libHSfilepath-1.2.0.1-ghc7.5.so]
 0x0000000000000001 (NEEDED)             Shared library: [libHSdeepseq-1.2.0.1-ghc7.5.so]
 0x0000000000000001 (NEEDED)             Shared library: [libHSarray-0.3.0.3-ghc7.5.so]
 0x0000000000000001 (NEEDED)             Shared library: [libHSbase-4.6.0.0-ghc7.5.so]
 0x0000000000000001 (NEEDED)             Shared library: [libHSinteger-gmp-0.3.0.0-ghc7.5.so]
 0x0000000000000001 (NEEDED)             Shared library: [libgmp.so.10]
 0x0000000000000001 (NEEDED)             Shared library: [libHSghc-prim-0.2.0.0-ghc7.5.so]
 0x0000000000000001 (NEEDED)             Shared library: [libHSrts-ghc7.5.so]
 0x0000000000000001 (NEEDED)             Shared library: [libm.so.6]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
 0x000000000000000f (RPATH)              Library rpath: [/home/user/dev/ghcbld/libraries/process/dist-install/build:/home/user/dev/ghcbld/libraries/directory/dist-install/build:/home/user/dev/ghcbld/libraries/unix/dist-install/build:/home/user/dev/ghcbld/libraries/bytestring/dist-install/build:/home/user/dev/ghcbld/libraries/time/dist-install/build:/home/user/dev/ghcbld/libraries/old-locale/dist-install/build:/home/user/dev/ghcbld/libraries/filepath/dist-install/build:/home/user/dev/ghcbld/libraries/deepseq/dist-install/build:/home/user/dev/ghcbld/libraries/array/dist-install/build:/home/user/dev/ghcbld/libraries/base/dist-install/build:/home/user/dev/ghcbld/libraries/integer-gmp/dist-install/build:/home/user/dev/ghcbld/libraries/ghc-prim/dist-install/build:/home/user/dev/ghcbld/rts/dist/build]
[...snip...]

2) If in the above 'collect2' command '--no-as-needed'/"--as-needed" put around '-lHSdirectory-1.1.0.1-ghc7.5', the linkage finishes OK:

$ readelf -d process001
Dynamic section at offset 0x2d38 contains 26 entries:
  Tag        Type                         Name/Value
 0x0000000000000001 (NEEDED)             Shared library: [libHSprocess-1.1.0.0-ghc7.5.so]
 0x0000000000000001 (NEEDED)             Shared library: [libHSdirectory-1.1.0.1-ghc7.5.so]
 0x0000000000000001 (NEEDED)             Shared library: [libHSbase-4.6.0.0-ghc7.5.so]
 0x0000000000000001 (NEEDED)             Shared library: [libHSghc-prim-0.2.0.0-ghc7.5.so]
 0x0000000000000001 (NEEDED)             Shared library: [libHSrts-ghc7.5.so]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
 0x000000000000000f (RPATH)              Library rpath: [/home/user/dev/ghcbld/libraries/process/dist-install/build:/home/user/dev/ghcbld/libraries/directory/dist-install/build:/home/user/dev/ghcbld/libraries/unix/dist-install/build:/home/user/dev/ghcbld/libraries/bytestring/dist-install/build:/home/user/dev/ghcbld/libraries/time/dist-install/build:/home/user/dev/ghcbld/libraries/old-locale/dist-install/build:/home/user/dev/ghcbld/libraries/filepath/dist-install/build:/home/user/dev/ghcbld/libraries/deepseq/dist-install/build:/home/user/dev/ghcbld/libraries/array/dist-install/build:/home/user/dev/ghcbld/libraries/base/dist-install/build:/home/user/dev/ghcbld/libraries/integer-gmp/dist-install/build:/home/user/dev/ghcbld/libraries/ghc-prim/dist-install/build:/home/user/dev/ghcbld/rts/dist/build]
[...snip...]

3) If '-u openpty' is appended to the above 'collect2' command, the linkage finishes OK:

$ readelf -d process001
Dynamic section at offset 0x2d48 contains 25 entries:
  Tag        Type                         Name/Value
 0x0000000000000001 (NEEDED)             Shared library: [libHSprocess-1.1.0.0-ghc7.5.so]
 0x0000000000000001 (NEEDED)             Shared library: [libHSbase-4.6.0.0-ghc7.5.so]
 0x0000000000000001 (NEEDED)             Shared library: [libHSghc-prim-0.2.0.0-ghc7.5.so]
 0x0000000000000001 (NEEDED)             Shared library: [libHSrts-ghc7.5.so]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
 0x000000000000000f (RPATH)              Library rpath: [/home/user/dev/ghcbld/libraries/process/dist-install/build:/home/user/dev/ghcbld/libraries/directory/dist-install/build:/home/user/dev/ghcbld/libraries/unix/dist-install/build:/home/user/dev/ghcbld/libraries/bytestring/dist-install/build:/home/user/dev/ghcbld/libraries/time/dist-install/build:/home/user/dev/ghcbld/libraries/old-locale/dist-install/build:/home/user/dev/ghcbld/libraries/filepath/dist-install/build:/home/user/dev/ghcbld/libraries/deepseq/dist-install/build:/home/user/dev/ghcbld/libraries/array/dist-install/build:/home/user/dev/ghcbld/libraries/base/dist-install/build:/home/user/dev/ghcbld/libraries/integer-gmp/dist-install/build:/home/user/dev/ghcbld/libraries/ghc-prim/dist-install/build:/home/user/dev/ghcbld/rts/dist/build]
[...snip...]
$ readelf -a process001
[...snip...]
Symbol table '.dynsym' contains 74 entries:
[...snip...]
    10: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND openpty
[...snip...]
Symbol table '.symtab' contains 161 entries:
[...snip...]
    84: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND openpty
[...snip...]

comment:4 Changed 3 years ago by marlowsd@…

commit 301b37255fb9ea3abd634cf9caf774c6dab647b7

Author: Simon Marlow <[email protected]>
Date:   Wed Jul 11 14:32:47 2012 +0100

    Link the extra-libraries when making a .so for a package (#7062)
    
    I don't think I completely understand what's going on here, but this
    does seem to fix it, and morally it seems like the right thing.

 rules/build-package-way.mk |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

comment:5 Changed 3 years ago by simonmar

  • Milestone changed from 7.6.1 to 7.4.3
  • Status changed from new to merge

comment:6 Changed 3 years ago by trommler

  • Cc ptrommler@… added

I came across the --as-needed issue when preparing packages for openSUSE's Build Service, where it is set by default.

The problem is that shared libraries that do not contain symbols that are undefined in any object (library or object file) up to the point in the command line where the library is mentioned (-l) will not be included in the ELF info and especially an Rpath will not be recorded. If the shared library is not installed in a standard directory, and Haskell libraries will not be in most Linux distributions, then it will not be found. If you symlinked those libraries from one of the standard directories then all works fine again.

As a temporary fix I put --no-as-needed into ghc's settings in a patch for openSUSE's ghc package.

To fix the --as-needed issue properly all libraries need to be linked to before libraries they depend on and for cycles one library needs to be linked twice. For Haskell packages dependency information in the packaging system could be used, for system libraries the the correct linking order would have to be specified in the extra-libraries field.

AFAIK Gentoo uses or at least recommends using --as-needed, too. Should we deal with this as a feature request in a different ticket?

comment:7 follow-ups: Changed 3 years ago by simonmar

@trommler does the patch fix it for you?

I still don't understand what was going wrong, and I'm afraid your explanation doesn't clarify things for me. The problem I encountered is that we had a link line like

  ... -lHSprocess -lHSunix -lutil ...

where libHSprocess depends on libHSunix which depends on 1libutil. But the linker reported a missing symbol openpty that is undefined in libHSunix and defined in libutil.

comment:8 in reply to: ↑ 7 ; follow-ups: Changed 3 years ago by trommler

Replying to simonmar:

@trommler does the patch fix it for you?

Yes, it fixes the linker issue.

The test, however, still fails for me. Now libHSunix*.so cannot be found:

=====> process001(dyn) 1 of 13 [0, 0, 0]
cd . && '/local/home/peter/ghc-HEAD-validate/inplace/bin/ghc-stage2' -fforce-recomp -dcore-lint -dcmm-lint -dno-debug-output -no-user-package-db -rtsopts  -fno-ghci-history -o process001 process001.hs -O -dynamic   >process001.comp.stderr 2>&1
cd . && ./process001    </dev/null >process001.run.stdout 2>process001.run.stderr
Wrong exit code (expected 0 , actual 127 )
Stdout:

Stderr:
./process001: error while loading shared libraries: libHSunix-2.5.1.0-ghc7.5.20120713.so: cannot open shared object file: No such file or directory

This matches nus' results with readelf above. In number 2) note that libHSunix... is missing in readelf -d process001 output. That means the Rpath to libHSunix... is also not included in process001 and hence the "No such file or directory."

If I disable --as-needed all process001 tests pass as expected.

On openSUSE we are using this patch (for ghc7.4.1) https://build.opensuse.org/package/view_file?file=ghc-suse-as-needed.patch&package=ghc&project=devel%3Alanguages%3Ahaskell&rev=ba0317723891490dee86f5cc014eff2c, which disables --as-needed for ghc.

comment:9 in reply to: ↑ 8 Changed 3 years ago by trommler

Replying to trommler:

The test, however, still fails for me. Now libHSunix*.so cannot be found:

This matches nus' results with readelf above. In number 2) note that libHSunix... is missing in readelf -d process001 output. That means the Rpath to libHSunix... is also not included in process001 and hence the "No such file or directory."

If I disable --as-needed all process001 tests pass as expected.

This issue seems to be related to the way shared libraries are being built for ghc and the use of RUNPATH/RPATH.

I think ticket #3072 would be a good place to discuss that.

comment:10 Changed 3 years ago by pgj

For your information, the patch for this ticket breaks the build on systems where libgmp is in EXTRA_LIBDIRS (e.g. /usr/local/lib on FreeBSD). Please find a minor enhancement attached to address this defect.

comment:11 in reply to: ↑ 7 Changed 3 years ago by nus

Replying to simonmar:

I still don't understand what was going wrong, and I'm afraid your explanation doesn't clarify things for me. The problem I encountered is that we had a link line like

  ... -lHSprocess -lHSunix -lutil ...

where libHSprocess depends on libHSunix which depends on 1libutil. But the linker reported a missing symbol openpty that is undefined in libHSunix and defined in libutil.

The sequence is
... -lHSprocess -lHSdirectory -lHSunix -lutil ...
Both 'HSprocess' and 'HSdirectory' depend on 'HSunix' which has 'openpty' undefined. With '--as-needed' only the first encounter of undefined 'openpty' gets satisfied from libutil.

comment:12 in reply to: ↑ 8 ; follow-up: Changed 3 years ago by nus

Replying to trommler:

Replying to simonmar:

@trommler does the patch fix it for you?

Yes, it fixes the linker issue.

The test, however, still fails for me. Now libHSunix*.so cannot be found:

=====> process001(dyn) 1 of 13 [0, 0, 0]
cd . && '/local/home/peter/ghc-HEAD-validate/inplace/bin/ghc-stage2' -fforce-recomp -dcore-lint -dcmm-lint -dno-debug-output -no-user-package-db -rtsopts  -fno-ghci-history -o process001 process001.hs -O -dynamic   >process001.comp.stderr 2>&1
cd . && ./process001    </dev/null >process001.run.stdout 2>process001.run.stderr
Wrong exit code (expected 0 , actual 127 )
Stdout:

Stderr:
./process001: error while loading shared libraries: libHSunix-2.5.1.0-ghc7.5.20120713.so: cannot open shared object file: No such file or directory

I'm not sure what's going on with that build. After applying http://hackage.haskell.org/trac/ghc/changeset/301b37255fb9ea3abd634cf9caf774c6dab647b7 to the pristine ghc-7.4.2 sources the process001(dyn) test from the 7.4.2 testsuite finishes OK here.

This matches nus' results with readelf above. In number 2) note that libHSunix... is missing in readelf -d process001 output. That means the Rpath to libHSunix... is also not included in process001 and hence the "No such file or directory."

Perhaps you're checking a different executable? Here RPATH of the produced executable has the path to the directory containing HSunix:

$ cd ~/dev/ghc-7.4.2/libraries/process/tests
$ /home/user/dev/ghc-7.4.2/inplace/bin/ghc-stage2 -fforce-recomp -dcore-lint -dcmm-lint -dno-debug-output -no-user-package-conf -rtsopts  -fno-ghci-history -o process001 process001.hs -O -dynamic
[1 of 1] Compiling Main             ( process001.hs, process001.o )
Linking process001 ...
$ readelf -d process001
Dynamic section at offset 0x2d98 contains 25 entries:
  Tag        Type                         Name/Value
 0x0000000000000001 (NEEDED)             Shared library: [libHSprocess-1.1.0.1-ghc7.4.2.so]
 0x0000000000000001 (NEEDED)             Shared library: [libHSbase-4.5.1.0-ghc7.4.2.so]
 0x0000000000000001 (NEEDED)             Shared library: [libHSghc-prim-0.2.0.0-ghc7.4.2.so]
 0x0000000000000001 (NEEDED)             Shared library: [libHSrts-ghc7.4.2.so]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
 0x000000000000000f (RPATH)              Library rpath: [/home/user/dev/ghc-7.4.2/libraries/process/dist-install/build:/home/user/dev/ghc-7.4.2/libraries/directory/dist-install/build:/home/user/dev/ghc-7.4.2/libraries/unix/dist-install/build:/home/user/dev/ghc-7.4.2/libraries/bytestring/dist-install/build:/home/user/dev/ghc-7.4.2/libraries/old-time/dist-install/build:/home/user/dev/ghc-7.4.2/libraries/old-locale/dist-install/build:/home/user/dev/ghc-7.4.2/libraries/filepath/dist-install/build:/home/user/dev/ghc-7.4.2/libraries/base/dist-install/build:/home/user/dev/ghc-7.4.2/libraries/integer-gmp/dist-install/build:/home/user/dev/ghc-7.4.2/libraries/ghc-prim/dist-install/build:/home/user/dev/ghc-7.4.2/rts/dist/build]
[...snip...]

From the libraries involved in the link, produced after applying the patch, HSprocess, HSdirectory, HSunix, only HSunix and HSdirectory have changed their DT_NEEDED tags in the dynamic sections, HSprocess remains same.

--- non-patched-elf-HSdirectory.so	2012-07-26 07:20:31.783083933 +0400
+++ patched-elf-HSdirectory.so	2012-07-26 09:26:01.773447158 +0400
@@ -1,9 +1,7 @@
 
-Dynamic section at offset 0x1a9e8 contains 30 entries:
+Dynamic section at offset 0x1aa08 contains 28 entries:
   Tag        Type                         Name/Value
  0x0000000000000001 (NEEDED)             Shared library: [libHSunix-2.5.1.1-ghc7.4.2.so]
- 0x0000000000000001 (NEEDED)             Shared library: [libutil.so.1]
- 0x0000000000000001 (NEEDED)             Shared library: [libdl.so.2]
[...snip...]
--- non-patched-elf-HSunix.so	2012-07-26 07:20:27.843084217 +0400
+++ patched-elf-HSunix.so	2012-07-26 09:25:44.133448671 +0400
@@ -1,6 +1,9 @@
 
-Dynamic section at offset 0xb1798 contains 26 entries:
+Dynamic section at offset 0xb1768 contains 29 entries:
   Tag        Type                         Name/Value
+ 0x0000000000000001 (NEEDED)             Shared library: [libutil.so.1]
+ 0x0000000000000001 (NEEDED)             Shared library: [libdl.so.2]
+ 0x0000000000000001 (NEEDED)             Shared library: [libpthread.so.0]
[...snip...]

comment:13 in reply to: ↑ 12 ; follow-up: Changed 3 years ago by trommler

Replying to nus:

Replying to trommler:
I'm not sure what's going on with that build. After applying http://hackage.haskell.org/trac/ghc/changeset/301b37255fb9ea3abd634cf9caf774c6dab647b7 to the pristine ghc-7.4.2 sources the process001(dyn) test from the 7.4.2 testsuite finishes OK here.

My executable also contains a RUNPATH tag in addition to the RPATH tag:

Dynamic section at offset 0x2d78 contains 27 entries:
  Tag        Type                         Name/Value
 0x0000000000000001 (NEEDED)             Shared library: [libHSprocess-1.1.0.2-ghc7.7.20120724.so]
 0x0000000000000001 (NEEDED)             Shared library: [libHSbase-4.6.0.0-ghc7.7.20120724.so]
 0x0000000000000001 (NEEDED)             Shared library: [libHSghc-prim-0.3.0.0-ghc7.7.20120724.so]
 0x0000000000000001 (NEEDED)             Shared library: [libHSrts-ghc7.7.20120724.so]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
 0x000000000000000f (RPATH)              Library rpath: [/home/peter/projects/haskell/ghc-validate/libraries/process/dist-install/build:/home/peter/projects/haskell/ghc-validate/libraries/directory/dist-install/build:/home/peter/projects/haskell/ghc-validate/libraries/unix/dist-install/build:/home/peter/projects/haskell/ghc-validate/libraries/bytestring/dist-install/build:/home/peter/projects/haskell/ghc-validate/libraries/time/dist-install/build:/home/peter/projects/haskell/ghc-validate/libraries/old-locale/dist-install/build:/home/peter/projects/haskell/ghc-validate/libraries/filepath/dist-install/build:/home/peter/projects/haskell/ghc-validate/libraries/deepseq/dist-install/build:/home/peter/projects/haskell/ghc-validate/libraries/array/dist-install/build:/home/peter/projects/haskell/ghc-validate/libraries/base/dist-install/build:/home/peter/projects/haskell/ghc-validate/libraries/integer-gmp/dist-install/build:/home/peter/projects/haskell/ghc-validate/libraries/ghc-prim/dist-install/build:/home/peter/projects/haskell/ghc-validate/rts/dist/build]
 0x000000000000001d (RUNPATH)            Library runpath: [/home/peter/projects/haskell/ghc-validate/libraries/process/dist-install/build:/home/peter/projects/haskell/ghc-validate/libraries/directory/dist-install/build:/home/peter/projects/haskell/ghc-validate/libraries/unix/dist-install/build:/home/peter/projects/haskell/ghc-validate/libraries/bytestring/dist-install/build:/home/peter/projects/haskell/ghc-validate/libraries/time/dist-install/build:/home/peter/projects/haskell/ghc-validate/libraries/old-locale/dist-install/build:/home/peter/projects/haskell/ghc-validate/libraries/filepath/dist-install/build:/home/peter/projects/haskell/ghc-validate/libraries/deepseq/dist-install/build:/home/peter/projects/haskell/ghc-validate/libraries/array/dist-install/build:/home/peter/projects/haskell/ghc-validate/libraries/base/dist-install/build:/home/peter/projects/haskell/ghc-validate/libraries/integer-gmp/dist-install/build:/home/peter/projects/haskell/ghc-validate/libraries/ghc-prim/dist-install/build:/home/peter/projects/haskell/ghc-validate/rts/dist/build]
 0x000000000000000c (INIT)               0x401c00
[snip]

The default on openSUSE's binutils is to --enable-new-dtags for ld. Then shared libraries will have both RUNPATH and RPATH. If I understand a discussion between Duncan Coutts and Andrew Suffield right http://www.haskell.org/pipermail/cvs-ghc/2010-January/052251.html then RUNPATH overrides RPATH . So I needed to look at RUNPATH. RUNPATH is only searched in the object that caused the load. Since libHSdirectory does not contain a RUNPATH but needs libHSunix the latter cannot be found. The RUNPATH in process001 will not be searched as process001 does not (directly) load libHSunix as a consequence of --asneeded.

A temporary solution would be to add --disable-new-dtags to the linker flags in settings. I'll prepare a patch for this and add it to the ticket.

Long term we should consider adding RUNPATHs to all libraries as Duncan suggested in the above posting.

This matches nus' results with readelf above. In number 2) note that libHSunix... is missing in readelf -d process001 output. That means the Rpath to libHSunix... is also not included in process001 and hence the "No such file or directory."

Perhaps you're checking a different executable? Here RPATH of the produced executable has the path to the directory containing HSunix:

What I said about RPATH was wrong. My RPATH looks exactly like yours. Sorry about the confusion.

comment:14 in reply to: ↑ 13 Changed 3 years ago by trommler

Replying to trommler:

A temporary solution would be to add --disable-new-dtags to the linker flags in settings. I'll prepare a patch for this and add it to the ticket.

Patch 0002-Do-not-add-RUNPATH-tag.patch adds --disable-new-dtags to linker flags if ld supports it. I do not check whether new dtags are enabled by default to keep the patch simple.

comment:15 Changed 3 years ago by simonmar

@trommler: please add a comment to the patch to indicate why the flag is necessary, and a reference to this ticket. Thanks.

Changed 3 years ago by trommler

Added comment to patch

comment:16 follow-up: Changed 3 years ago by pgj

Could somebody please un-break the FreeBSD builder clients by pushing my patch? They have been broken for about a month because of the currently applied patch. Thank you in advance!

comment:17 in reply to: ↑ 16 ; follow-ups: Changed 3 years ago by simonmar

  • Status changed from merge to new

Replying to pgj:

Could somebody please un-break the FreeBSD builder clients by pushing my patch? They have been broken for about a month because of the currently applied patch. Thank you in advance!

I'm a little unsure about this patch, which is why I asked you to add a comment. But your comment just points back to this ticket, and I'm none the wiser! You mentioned that this is a temporary fix, which also makes me a bit nervous. I'm not sure whether this will have implications for other platforms or not.

What I'd like to see is

  • a consise description of the problem
  • an explanation of the workaround
  • if this is a temporary workaround, what is the right fix?
  • when can we remove the temporary workaround?
  • what are the implications for other platforms?

comment:18 in reply to: ↑ 17 ; follow-up: Changed 3 years ago by pgj

Replying to simonmar:

Replying to pgj:

Could somebody please un-break the FreeBSD builder clients by pushing my patch? They have been broken for about a month because of the currently applied patch. Thank you in advance!

I'm a little unsure about this patch, which is why I asked you to add a comment.

Sorry, I do not understand. I have only seen a message addressed to trommler (c.f. your comment above). Perhaps there is a confusion here...?

My patch only adds a missing flag to the already committed version of this modification so it unbreaks the build on FreeBSD (and on any other system where libraries like gmp live under "non-standard" dictionaries, e.g. /usr/local/lib). I tested it, it works -- otherwise I would have not attached it.

comment:19 in reply to: ↑ 18 ; follow-up: Changed 3 years ago by simonmar

Replying to pgj:

Sorry, I do not understand. I have only seen a message addressed to trommler (c.f. your comment above). Perhaps there is a confusion here...?

Sorry, my mistake! I'll get your patch committed ASAP.

comment:20 in reply to: ↑ 19 Changed 3 years ago by pgj

Replying to simonmar:

Sorry, my mistake! I'll get your patch committed ASAP.

Thank you very much.

comment:21 in reply to: ↑ 17 ; follow-up: Changed 3 years ago by trommler

Replying to simonmar:

I'm a little unsure about this patch, which is why I asked you to add a comment. But your comment just points back to this ticket, and I'm none the wiser! You mentioned that this is a temporary fix, which also makes me a bit nervous. I'm not sure whether this will have implications for other platforms or not.

The flag is ELF specific.

What I'd like to see is

  • a consise description of the problem

If ld was patched to include the new dynamic tags and as needed is also enabled then Haskell libraries will not be found if they are not installed in a standard dynamic linker path. The reason is that unlike the old RPATH dynamic tag the new RUNPATH dynamic tag applies only libraries directly loaded by the object containing the RUNPATH tag.

GHC libraries do not set a RUNPATH or RPATH tag for other GHC libraries they depend on (see libHSunix above) and hence the library cannot be found unless it is in the default linker path or included in LD_LIBRARY_PATH.

  • an explanation of the workaround

The workaround explicitly requests the old dynamic tags to be generated which is still the standard on vanilla binutils. Some distributions, however, patch binutils to include the new dynamic tags.

  • if this is a temporary workaround, what is the right fix?

The right fix is to include a RUNPATH for all dependent Haskell libraries when linking GHC's libraries. The handling of dlopen in the presence of RUNPATH has been changed as well, so there might be some implications for Linker.c too.

  • when can we remove the temporary workaround?

After the above fix is done.

  • what are the implications for other platforms?

I do not expect implications for other platforms as the flag is ELF specific and the patch adds a check to configure if the flag is supported by ld and only if it is adds he flag to the linker flags.

If binutils was not patched to include RUNPATH then everything will work as before. I tested that on Suse Linux Enterprise Sever 11 SP1 and SP2 for both i386 and x86_64.

comment:22 Changed 3 years ago by igloo

  • Milestone changed from 7.4.3 to 7.6.2

comment:23 in reply to: ↑ 21 ; follow-up: Changed 2 years ago by markwright

Replying to trommler:

GHC libraries do not set a RUNPATH or RPATH tag for other GHC libraries they depend on (see libHSunix above) and hence the library cannot be found unless it is in the default linker path or included in LD_LIBRARY_PATH.

I added this patch to #3072 to add an rpath to the ghc core libs

http://hackage.haskell.org/trac/ghc/attachment/ticket/3072/ghc-7.7.20121101-corelibs-rpath.patch

comment:24 in reply to: ↑ 23 Changed 2 years ago by trommler

Replying to markwright:

Replying to trommler:

I added this patch to #3072 to add an rpath to the ghc core libs

I built HEAD and the patch fixes the issue.

The test, however, still fails with the same error. To fix that error we need to do the same thing in testsuite for Linux that we do for OS X and for Windows already: Set an environment variable to point ld.so to the freshly built libraries. Otherwise the system libraries will be used (if present) and this is not what we want in testsuite.

For builds that link with --enable-new-dtags (.so contains both RUNPATH and RPATH) setting LD_LIBRARY_PATH would be sufficient. If only RPATH is set (--disable-new-dtags), however, LD_PRELOAD must be used to override RPATH. LD_PRELOAD works in both cases, so LD_PRELOAD should be set.

I could create a patch for testsuite to implement that.

Are there plans to merge markwright's patch into 7.6?

comment:25 follow-up: Changed 2 years ago by igloo

  • Status changed from new to infoneeded

The test is passing in HEAD for me, and isn't listed as a failure in http://www.haskell.org/pipermail/cvs-ghc/2012-November/078417.html

Can you tell me how I can reproduce a problem, please?

comment:26 in reply to: ↑ 25 Changed 2 years ago by trommler

  • Status changed from infoneeded to new

Replying to igloo:

Can you tell me how I can reproduce a problem, please?

The problem is triggered by two flags set in ld: --enable-new-dtags and --as-needed.
Both settings are not the default settings in a vanilla ld but Linux distributions (openSUSE in my case) change those defaults and that is the reason, I am still seeing a failure on openSUSE.

To reproduce the issue:

  1. Configure ghc that --enable-new-dtags and --as-needed are passed to ld.
  1. Build ghc
  1. Run make TEST=process001

comment:27 Changed 2 years ago by trommler

Here is the patch I promised in comment 23: http://hackage.haskell.org/trac/ghc/attachment/ticket/7062/0001-Set-LD_LIBRARY_PATH-on-Linux.patch

See http://www.sco.com/developers/gabi/latest/ch5.dynamic.html under heading "Shared Object Dependencies" for more details on how a shared library is found in the presence of RUNPATH (introduced by ld flag --enable-new-dtags).

Changed 2 years ago by trommler

Updated patch

comment:28 Changed 2 years ago by ian@…

commit 9d9d09defda3dfc2362785608110e56d1fc1f3b2

Author: Ian Lynagh <[email protected]>
Date:   Fri Jan 4 18:43:19 2013 +0000

    Add a -rpath entry for the RTS library, so that it can find libffi
    
    This fixes dynamic library resolution when --enable-new-dtags is used
    (#7062).
    
    When --enable-new-dtags is used when linking an executable, a RUNPATH as
    well as RPATH is set. The linker then ignores RPATH, and RUNPATH is only
    used for directly (not transitively) needed libraries. As the program
    doesn't directly need libffi, it isn't found.

 rts/ghc.mk |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

comment:29 Changed 2 years ago by igloo

  • Resolution set to fixed
  • Status changed from new to closed

OK, the above patch should fix this. Please reopen and give details if you still have problems.

Note: See TracTickets for help on using tickets.