Change to DSO-linking semantics of the compiler

Roland McGrath roland at redhat.com
Mon Jan 11 23:22:38 UTC 2010


> SystemTap is failing on pthread_cancel, which is odd since we have no
> mention of pthread in our own sources.  It seems to be pulled in by some
> headers in the STL.  Consider this minimal example:
> 
> $ cat string.cxx
> #include <string>
> int main()
> {
>     return std::string("foo").length() != 3;
> }
> $ g++ -c string.cxx
> $ nm -C string.o
>                  U _Unwind_Resume
>                  U std::string::length() const
>                  U std::allocator<char>::allocator()
>                  U std::allocator<char>::~allocator()
>                  U std::basic_string<char, std::char_traits<char>,
> std::allocator<char> >::basic_string(char const*, std::allocator<char>
> const&)
>                  U std::basic_string<char, std::char_traits<char>,
> std::allocator<char> >::~basic_string()
> 0000000000000008 r __gthread_active_p()::__gthread_active_ptr
>                  U __gxx_personality_v0
> 0000000000000000 T main
>                  w pthread_cancel
> $ g++ -o string string.o
> 
> This is fine, becauses __gthread_active_p is just using the fact that
> the weak pthread_cancel symbol becomes 0 if libpthread isn't linked.

Right.  There's no dependency if it's a weak reference.

> But if one of your dependent libraries uses pthreads, suddenly the main
> executable gets the normal pthread_cancel symbol too, and the new linker
> serves up death:
> 
> $ g++ -o string string.o -ldb
> /usr/bin/ld.bfd: string.11980.test: undefined reference to symbol
> 'pthread_cancel@@GLIBC_2.2.5'
> /usr/bin/ld.bfd: note: 'pthread_cancel@@GLIBC_2.2.5' is defined in DSO
> /lib64/libpthread.so.0 so try adding it to the linker command line
> /lib64/libpthread.so.0: could not read symbols: Invalid operation
> *** /usr/bin/ld: ld behavior mismatch! ***
> *** /usr/bin/ld.bfd succeeeded ***
> *** /usr/bin/ld.bfd --no-add-needed exits 1 ***
> *** arguments: --eh-frame-hdr --build-id -m elf_x86_64 --hash-style=gnu
> -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o string
> /usr/lib/gcc/x86_64-redhat-linux/4.4.2/../../../../lib64/crt1.o
> /usr/lib/gcc/x86_64-redhat-linux/4.4.2/../../../../lib64/crti.o
> /usr/lib/gcc/x86_64-redhat-linux/4.4.2/crtbegin.o
> -L/usr/lib/gcc/x86_64-redhat-linux/4.4.2
> -L/usr/lib/gcc/x86_64-redhat-linux/4.4.2
> -L/usr/lib/gcc/x86_64-redhat-linux/4.4.2/../../../../lib64
> -L/lib/../lib64 -L/usr/lib/../lib64
> -L/usr/lib/gcc/x86_64-redhat-linux/4.4.2/../../.. string.o -ldb -lstdc++
> -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc
> /usr/lib/gcc/x86_64-redhat-linux/4.4.2/crtend.o
> /usr/lib/gcc/x86_64-redhat-linux/4.4.2/../../../../lib64/crtn.o
> collect2: ld returned 1 exit status
> 
> So it seems that now I have to know what my dependent libraries are
> linking to, which I thought was exactly what we were trying to eliminate
> with these new linking semantics.

I think these are not the semantics they're supposed to be.  Nick?

I wonder if gold behaves that way.  It's a subtle point, I supppose.
The weak undefined reference does need to be associated with the real
definition to some degree, in that it uses that symbol version assocation.

But clearly the mere presence of a weak reference should never trigger any
kind of "undefined reference" error.

> 75 of the failed packages have an undefined reference to pthread_cancel,
> probably for the same reason as above.

We'll fix the toolchain and/or libstdc++ as needed for this.
Those packages should not need a change just because of this issue.


Thanks,
Roland


More information about the devel mailing list