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

Lee Noar leenoar at sky.com
Wed Jul 30 13:18:22 PDT 2008

John Tytgat wrote:
> In message <48904FAE.4090002 at sky.com>
>           Lee Noar <leenoar at sky.com> wrote:
>> So far, I can tell you that the function that makes the branch to 0 is
>> std::locale::_S_initialize() in libstdc++. I think that the function it 
>> is attempting (and failing) to call is gthread_once(), but I can't find 
>> a definition for it in the binary (although all the pthread ones are 
>> there). This should cause a build time linker error, however, if 
>> gthread_once is declared as weak, then that may explain why there was no 
>> error and a NULL value used instead. So it seems that __GTHREADS is 
>> defined, but there's no implementation to bind it to pthreads in 
>> UnixLib? Or perhaps __GTHREADS shouldn't be defined at all?
> The gthread stuff is gcc specific and gets implemented using one of
> several possible thread implementations.  We're using the pthread one
> and a quick check seems to confirm that is really the case.

I've dug a bit deeper and found that there is a gthread implementation 
which is a veneer for UnixLib pthreads as you say.

The assembler for std::locale::_S_initialize() 
(libstdc++-v3/locale_init.cc) looks like this:

	.global	_ZNSt6locale13_S_initializeEv
	.type	_ZNSt6locale13_S_initializeEv, %function
	@ args = 0, pretend = 0, frame = 0, outgoing = 0
	@ frame_needed = 1, uses_anonymous_args = 0
	mov	ip, sp
	stmfd	sp!, {fp, ip, lr, pc}
	sub	fp, ip, #4
	cmp	sp, sl
	bllt	__rt_stkovf_split_small
	ldr	r3, .L83
	cmp	r3, #0
	ldr	r1, .L83+4
	ldr	r0, .L83+8
	bne	.L81
	ldr	r3, .L83+12
	ldr	r2, [r3, #0]
	cmp	r2, #0
	ldmneea	fp, {fp, sp, pc}
	bl	_ZNSt6locale18_S_initialize_onceEv
	ldmea	fp, {fp, sp, pc}
	ldr	r3, .L83+16
	mov	lr, pc
	mov	pc, r3
	ldr	r3, .L83+12
	ldr	r2, [r3, #0]
	cmp	r2, #0
	ldmneea	fp, {fp, sp, pc}
	b	.L82
	.align	2
	.word	_Z22__gthrw_pthread_cancelP16__pthread_thread
	.word	_ZNSt6locale18_S_initialize_onceEv
	.word	_ZNSt6locale7_S_onceE
	.word	_ZNSt6locale10_S_classicE
	.word	_Z20__gthrw_pthread_oncePiPFvvE

Note that the last word value above (_Z20__gthrw_pthread_oncePiPFvvE) is 
the one that is NULL and causes the branch through 0. This is defined as 
a weakref to pthread_once:

	.weakref _Z20__gthrw_pthread_oncePiPFvvE,pthread_once

AFAICT, ".weakref sym1, sym2" means resolve to sym2 (if available) else 
zero. Using "nm -n" on the binary lists pthread_once as a weak undefined 
symbol, so the linker isn't pulling in the definition, pthread_once 
isn't available and the weakref resolves to NULL.

 > Would it be possible to craft a small C++ testcase showing this
 > problem so that I could have a further look please ?

There must be a specific section of libstdc++ that these programs are 
using to trigger this bug as I don't think all C++ programs are 
affected. I'll see if I can isolate it.


More information about the gcc mailing list