[gccsdk] Problems running C++ programs compiled with GCC4

Lee Noar leenoar at sky.com
Mon Aug 4 12:06:50 PDT 2008


Lee Noar wrote:
> John Tytgat wrote:
>> Would it be possible to craft a small C++ testcase showing this problem
>> so that I could have a further look please ?
> 
> The following code shows the problem and must be compiled as c++.
> 
> --8<-- test.cc ----
> 
> #include <stdio.h>
> #include <pthread.h>
> 
> extern void dummy(void)
> {
>   /* Never called, just needs to be present. */
>   pthread_cancel(NULL);
> }
> 
> int main(void)
> {
>   printf("Hello World\n");
> 
>   return 0;
> }
> 
> --8<---------------
> 
> I compiled with:
> 
> arm-unknown-riscos-g++ test.cc -static -O2 -o test,e1f
> 
> The gthread implementation checks for an active thread system by 
> checking for the existence of pthread_cancel (__gthread_active_p() 
> gthr-posix.h). Tutris and I suspect Wesnoth use threads and therefore 
> pthread_cancel is linked in. If pthread_cancel is not present in the 
> binary, then the offending code is skipped and the program works.

It would seem that weakrefs were added to GCC and GAS to overcome
the problem we're seeing. See this post for an explanation of weakrefs:

<http://www.sourceware.org/ml/binutils/2005-10/msg00107.html>

it specifically mentions libstdc++ and the gthr-* headers. Linux GCC
correctly pulls in the pthread functions - whether that is because it's
a separate library in its own right, I don't know.

I have a solution, but I'm not sure whether you'd call it a fix, a 
workaround or a bodge which is why I'll describe it here first before 
committing anything.

The problem is that several pthread functions are not pulled in by the 
linker because the references to them are weak. I've replaced the empty 
version of libpthread.a with one that contains:

extern void pthread_once(void);
extern void pthread_getspecific(void);
extern void pthread_key_create(void);
extern void pthread_key_delete(void);
extern void pthread_setspecific(void);

static void pthread_dummy(void)
{
   pthread_once();
   pthread_getspecific();
   pthread_key_create();
   pthread_key_delete();
   pthread_setspecific();
}

By then adding:

-Wl,--whole-archive -lpthread -Wl,--no-whole-archive

to the link line (which could be done automatically), the weakrefs are 
resolved. Tutris works using this. This is only necessary for static c++ 
programs, ironically, dynamically linked code is OK.

Does this seem a reasonable fix?

Lee.




More information about the gcc mailing list