Change to DSO-linking semantics of the compiler

Nick Clifton nickc at redhat.com
Wed Jan 13 16:24:13 UTC 2010


Hi Guys,

>> 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
>>                   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.
>>
>> 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

But, you have added an explicit dependency upon libdb to your executable 
by mentioning -ldb on the gcc command line.  Therefore libdb will be 
loaded at execution start-up.  But libdb has a dependency upon 
libpthread, so that library will also be loaded at execution start-up. 
Hence when you run 'string' the pthread_cancel symbol will be resolved 
and so 'string' really does now have a resolved reference to 
pthread_cancel.  Hence the linker is correct in complaining that you 
have a reference to a symbol that is defined in a library which have not 
included on the linker command line.

At least that is how I see it at the moment.

The point being that because you are using -ldb you have inherited a 
need for the pthread library as well.  Hence this works:

   g++ o string string.o -ldb -lpthread

Cheers
   Nick


More information about the devel mailing list