static object constructors never called

I have a .cc file within a library which contains the following code:

static string testString = “TestString”;

The resulting library is statically linked with two different executables
but using the same command-line options to qcc (and thus ld). Let’s call
these executables A and B.

In executable A, the constructor for testString is (correctly) called before
main().
In exectuable B, the constructor for testString is never called. ********

I have verified this in ddd.
Both executables use the objects/methods from the offending source file.
The same thing happens with both the Dinkum and GCC libs.
We are using the release version of 6.2.

I guess it must be a link (ld) problem but this has me totally stumped.
Can anyone offer any explanation or suggestion on how to track this down?

Rob Rutherford
Ruzz Technology

“Robert Rutherford” <ruzz@NoSpamPlease.ruzz.com> wrote in message
news:agam44$427$1@inn.qnx.com

I have a .cc file within a library which contains the following code:

static string testString = “TestString”;

The resulting library is statically linked with two different executables
but using the same command-line options to qcc (and thus ld). Let’s call
these executables A and B.

In executable A, the constructor for testString is (correctly) called
before
main().
In exectuable B, the constructor for testString is never called. ********

Is testString ever referenced in executable B?

Kris

“Kris Warkentin” <kewarken@qnx.com> wrote in message
news:agc13s$7rn$1@nntp.qnx.com

“Robert Rutherford” <> ruzz@NoSpamPlease.ruzz.com> > wrote in message
news:agam44$427$> 1@inn.qnx.com> …
I have a .cc file within a library which contains the following code:

static string testString = “TestString”;

The resulting library is statically linked with two different
executables
but using the same command-line options to qcc (and thus ld). Let’s call
these executables A and B.

In executable A, the constructor for testString is (correctly) called
before
main().
In exectuable B, the constructor for testString is never called.


Is testString ever referenced in executable B?

Kris

Yes. Both executables contain

cout << "Test string is " << testString << endl;
testString = “new value”;

For executable A, this works as expected.
For executable B,
If using Dinkum, testString displays as an empty string but if you check
with ddd/gdb it is not properly constructed. After the assignment all is
well.
If using GCC libs, it displays as an empty string but SIGSEGVs on the
assignment as it tries to dereference an internal pointer within the
invalid/unconstructed string object

Robert

I don’t suppose you can boil the two cases down into a small
testcase? :v)

Robert Rutherford <ruzz@nospamplease.ruzz.com> wrote:

I have a .cc file within a library which contains the following code:

static string testString = “TestString”;

The resulting library is statically linked with two different executables
but using the same command-line options to qcc (and thus ld). Let’s call
these executables A and B.

In executable A, the constructor for testString is (correctly) called before
main().
In exectuable B, the constructor for testString is never called. ********

I have verified this in ddd.
Both executables use the objects/methods from the offending source file.
The same thing happens with both the Dinkum and GCC libs.
We are using the release version of 6.2.

I guess it must be a link (ld) problem but this has me totally stumped.
Can anyone offer any explanation or suggestion on how to track this down?

Rob Rutherford
Ruzz Technology




cburgess@qnx.com

Thanks Colin.

I am currently trying to achieve this - or at least narrow it down to the
smallest set of differences that cause the problem. Of course all the
trivial cases work.

I was actually hoping that you might have some suggestions on
tools/tips/tricks to help diagnose this kind of problem - for example is it
possible (using objdump or gdb or …) to actually have a look at all the
static initalisers/constructors that will be called prior to main().

Robert

“Colin Burgess” <cburgess@qnx.com> wrote in message
news:ages13$e48$1@nntp.qnx.com

I don’t suppose you can boil the two cases down into a small
testcase? :v)

Robert Rutherford <> ruzz@nospamplease.ruzz.com> > wrote:
I have a .cc file within a library which contains the following code:

static string testString = “TestString”;

The resulting library is statically linked with two different
executables
but using the same command-line options to qcc (and thus ld). Let’s call
these executables A and B.

In executable A, the constructor for testString is (correctly) called
before
main().
In exectuable B, the constructor for testString is never called.


I have verified this in ddd.
Both executables use the objects/methods from the offending source file.
The same thing happens with both the Dinkum and GCC libs.
We are using the release version of 6.2.

I guess it must be a link (ld) problem but this has me totally stumped.
Can anyone offer any explanation or suggestion on how to track this
down?

Rob Rutherford
Ruzz Technology





\

cburgess@qnx.com

OK I’ve figured out that the key is the .ctors section within the ELF file.
At least now I can quickly check whether things have worked by doing
“objdump -s -j .ctors”.

And I’ve found something else interesting:
In the failing file, all the correct constructors are actually listed in the
…ctors section, but the symbol CTOR_END (and a 0x0 entry) seems to be
placed prematurely early within the section.

For example, for executable B (failing) we have:

B (not working): file format elf32-i386

Contents of section .ctors:
809c794 ffffffff 10300508 143b0508 f45f0508
809c7a4 5c7a0508 10840508 00000000 c0870508
809c7b4 188d0508 44a20508 d0a20508 58bc0508
809c7c4 b8c00508 6cca0508 3ccf0508 acf30508
809c7d4 a8f40508
Disassembly of section .ctors:

0809c794 <CTOR_LIST>:
809c794: ff ff ff ff 10 30 05 08 14 3b 05 08 f4 5f 05 08
809c7a4: 5c 7a 05 08 10 84 05 08

0809c7ac <CTOR_END>:
809c7ac: 00 00 00 00 c0 87 05 08 18 8d 05 08 44 a2 05 08
809c7bc: d0 a2 05 08 58 bc 05 08 b8 c0 05 08 6c ca 05 08
809c7cc: 3c cf 05 08 ac f3 05 08 a8 f4 05 08

One particular constructor (group) that isn’t called (but should be) has, in
this case, the address 0805a244. You will see that this is actually present
in the section but AFTER the 0x0 and symbol CTOR_END. I’m no
ELF/startup expert but the code in __do_global_ctors_aux looks like it
relies on the symbol CTOR_END to figure out where to start. It then
works backwards until it finds FFFFFFFF. This would explain why our
constructors aren’t called.

In the working case (below), the symbol CTOR_END is towards the end of
the section and most/all of the necessary constructors preceed it. (I can’t
explain the extra items even in this case - maybe this is still not 100%
working???). By comparison to an objdump from another C++ application (e.g.
ddd) we see that the only 0x0 in the .ctors section is to be found at the
end.

Colin, does this give you anything to go on?
How exactly is the .ctors section built?
Should the CTOR_END symbol be right at the end of the section? Or is the
problem actually the NULL (0x0) in the middle of the table?

A (working?): file format elf32-i386

Contents of section .ctors:
80c7fc8 ffffffff 94230508 382c0508 18300508
80c7fd8 68420508 244f0508 7c540508 805f0508
80c7fe8 60840508 fc900508 48940508 f4a30508
80c7ff8 5cae0508 88c30508 14c40508 e4c80508
80c8008 6ce20508 dc060608 f41e0608 fc2e0608
80c8018 40340608 384c0608 004f0608 00000000
80c8028 b0520608 3c580608
Disassembly of section .ctors:

080c7fc8 <CTOR_LIST>:
80c7fc8: ff ff ff ff 94 23 05 08 38 2c 05 08 18 30 05 08
80c7fd8: 68 42 05 08 24 4f 05 08 7c 54 05 08 80 5f 05 08
80c7fe8: 60 84 05 08 fc 90 05 08 48 94 05 08 f4 a3 05 08
80c7ff8: 5c ae 05 08 88 c3 05 08 14 c4 05 08 e4 c8 05 08
80c8008: 6c e2 05 08 dc 06 06 08 f4 1e 06 08 fc 2e 06 08
80c8018: 40 34 06 08 38 4c 06 08 00 4f 06 08

080c8024 <CTOR_END>:
80c8024: 00 00 00 00 b0 52 06 08 3c 58 06 08

Rob Rutherford

“Robert Rutherford” <ruzz@NoSpamPlease.ruzz.com> wrote in message
news:agg22h$75r$1@inn.qnx.com

Thanks Colin.

I am currently trying to achieve this - or at least narrow it down to the
smallest set of differences that cause the problem. Of course all the
trivial cases work.

I was actually hoping that you might have some suggestions on
tools/tips/tricks to help diagnose this kind of problem - for example is
it
possible (using objdump or gdb or …) to actually have a look at all the
static initalisers/constructors that will be called prior to main().

Robert

“Colin Burgess” <> cburgess@qnx.com> > wrote in message
news:ages13$e48$> 1@nntp.qnx.com> …
I don’t suppose you can boil the two cases down into a small
testcase? :v)

Robert Rutherford <> ruzz@nospamplease.ruzz.com> > wrote:
I have a .cc file within a library which contains the following code:

static string testString = “TestString”;

The resulting library is statically linked with two different
executables
but using the same command-line options to qcc (and thus ld). Let’s
call
these executables A and B.

In executable A, the constructor for testString is (correctly) called
before
main().
In exectuable B, the constructor for testString is never called.


I have verified this in ddd.
Both executables use the objects/methods from the offending source
file.
The same thing happens with both the Dinkum and GCC libs.
We are using the release version of 6.2.

I guess it must be a link (ld) problem but this has me totally
stumped.
Can anyone offer any explanation or suggestion on how to track this
down?

Rob Rutherford
Ruzz Technology





\

cburgess@qnx.com

Yes, this is WRONG WRONG WRONG!

The ctors section is basically put together in the order it gets
presented to the linker.

So crtbeginC++.o and crtendC++.o
Can you generate a map file (-M) and grep for LOAD in it, and post that?

Robert Rutherford <ruzz@nospamplease.ruzz.com> wrote:

OK I’ve figured out that the key is the .ctors section within the ELF file.
At least now I can quickly check whether things have worked by doing
“objdump -s -j .ctors”.

And I’ve found something else interesting:
In the failing file, all the correct constructors are actually listed in the
.ctors section, but the symbol CTOR_END (and a 0x0 entry) seems to be
placed prematurely early within the section.

For example, for executable B (failing) we have:

B (not working): file format elf32-i386

Contents of section .ctors:
809c794 ffffffff 10300508 143b0508 f45f0508
809c7a4 5c7a0508 10840508 00000000 c0870508
809c7b4 188d0508 44a20508 d0a20508 58bc0508
809c7c4 b8c00508 6cca0508 3ccf0508 acf30508
809c7d4 a8f40508
Disassembly of section .ctors:

0809c794 <CTOR_LIST>:
809c794: ff ff ff ff 10 30 05 08 14 3b 05 08 f4 5f 05 08
809c7a4: 5c 7a 05 08 10 84 05 08

0809c7ac <CTOR_END>:
809c7ac: 00 00 00 00 c0 87 05 08 18 8d 05 08 44 a2 05 08
809c7bc: d0 a2 05 08 58 bc 05 08 b8 c0 05 08 6c ca 05 08
809c7cc: 3c cf 05 08 ac f3 05 08 a8 f4 05 08

One particular constructor (group) that isn’t called (but should be) has, in
this case, the address 0805a244. You will see that this is actually present
in the section but AFTER the 0x0 and symbol CTOR_END. I’m no
ELF/startup expert but the code in __do_global_ctors_aux looks like it
relies on the symbol CTOR_END to figure out where to start. It then
works backwards until it finds FFFFFFFF. This would explain why our
constructors aren’t called.

In the working case (below), the symbol CTOR_END is towards the end of
the section and most/all of the necessary constructors preceed it. (I can’t
explain the extra items even in this case - maybe this is still not 100%
working???). By comparison to an objdump from another C++ application (e.g.
ddd) we see that the only 0x0 in the .ctors section is to be found at the
end.

Colin, does this give you anything to go on?
How exactly is the .ctors section built?
Should the CTOR_END symbol be right at the end of the section? Or is the
problem actually the NULL (0x0) in the middle of the table?

A (working?): file format elf32-i386

Contents of section .ctors:
80c7fc8 ffffffff 94230508 382c0508 18300508
80c7fd8 68420508 244f0508 7c540508 805f0508
80c7fe8 60840508 fc900508 48940508 f4a30508
80c7ff8 5cae0508 88c30508 14c40508 e4c80508
80c8008 6ce20508 dc060608 f41e0608 fc2e0608
80c8018 40340608 384c0608 004f0608 00000000
80c8028 b0520608 3c580608
Disassembly of section .ctors:

080c7fc8 <CTOR_LIST>:
80c7fc8: ff ff ff ff 94 23 05 08 38 2c 05 08 18 30 05 08
80c7fd8: 68 42 05 08 24 4f 05 08 7c 54 05 08 80 5f 05 08
80c7fe8: 60 84 05 08 fc 90 05 08 48 94 05 08 f4 a3 05 08
80c7ff8: 5c ae 05 08 88 c3 05 08 14 c4 05 08 e4 c8 05 08
80c8008: 6c e2 05 08 dc 06 06 08 f4 1e 06 08 fc 2e 06 08
80c8018: 40 34 06 08 38 4c 06 08 00 4f 06 08

080c8024 <CTOR_END>:
80c8024: 00 00 00 00 b0 52 06 08 3c 58 06 08

Rob Rutherford

“Robert Rutherford” <> ruzz@NoSpamPlease.ruzz.com> > wrote in message
news:agg22h$75r$> 1@inn.qnx.com> …
Thanks Colin.

I am currently trying to achieve this - or at least narrow it down to the
smallest set of differences that cause the problem. Of course all the
trivial cases work.

I was actually hoping that you might have some suggestions on
tools/tips/tricks to help diagnose this kind of problem - for example is
it
possible (using objdump or gdb or …) to actually have a look at all the
static initalisers/constructors that will be called prior to main().

Robert

“Colin Burgess” <> cburgess@qnx.com> > wrote in message
news:ages13$e48$> 1@nntp.qnx.com> …
I don’t suppose you can boil the two cases down into a small
testcase? :v)

Robert Rutherford <> ruzz@nospamplease.ruzz.com> > wrote:
I have a .cc file within a library which contains the following code:

static string testString = “TestString”;

The resulting library is statically linked with two different
executables
but using the same command-line options to qcc (and thus ld). Let’s
call
these executables A and B.

In executable A, the constructor for testString is (correctly) called
before
main().
In exectuable B, the constructor for testString is never called.


I have verified this in ddd.
Both executables use the objects/methods from the offending source
file.
The same thing happens with both the Dinkum and GCC libs.
We are using the release version of 6.2.

I guess it must be a link (ld) problem but this has me totally
stumped.
Can anyone offer any explanation or suggestion on how to track this
down?

Rob Rutherford
Ruzz Technology





\

cburgess@qnx.com


cburgess@qnx.com

Colin Burgess <cburgess@qnx.com> wrote:

Yes, this is WRONG WRONG WRONG!

The ctors section is basically put together in the order it gets
presented to the linker.

So crtbeginC++.o and crtendC++.o

sorry, I didn’t finish my thought there.

You should have all crt files wrapping your objects. The only way
I can think of you getting the below result is if this is not the
case, hence the request for the -M, which will show the load order.
Actually, I’d love to see the link line as well.

You also get the weird bug of the week award. :v)

Can you generate a map file (-M) and grep for LOAD in it, and post that?

Robert Rutherford <> ruzz@nospamplease.ruzz.com> > wrote:
OK I’ve figured out that the key is the .ctors section within the ELF file.
At least now I can quickly check whether things have worked by doing
“objdump -s -j .ctors”.

And I’ve found something else interesting:
In the failing file, all the correct constructors are actually listed in the
.ctors section, but the symbol CTOR_END (and a 0x0 entry) seems to be
placed prematurely early within the section.

For example, for executable B (failing) we have:

B (not working): file format elf32-i386

Contents of section .ctors:
809c794 ffffffff 10300508 143b0508 f45f0508
809c7a4 5c7a0508 10840508 00000000 c0870508
809c7b4 188d0508 44a20508 d0a20508 58bc0508
809c7c4 b8c00508 6cca0508 3ccf0508 acf30508
809c7d4 a8f40508
Disassembly of section .ctors:

0809c794 <CTOR_LIST>:
809c794: ff ff ff ff 10 30 05 08 14 3b 05 08 f4 5f 05 08
809c7a4: 5c 7a 05 08 10 84 05 08

0809c7ac <CTOR_END>:
809c7ac: 00 00 00 00 c0 87 05 08 18 8d 05 08 44 a2 05 08
809c7bc: d0 a2 05 08 58 bc 05 08 b8 c0 05 08 6c ca 05 08
809c7cc: 3c cf 05 08 ac f3 05 08 a8 f4 05 08

One particular constructor (group) that isn’t called (but should be) has, in
this case, the address 0805a244. You will see that this is actually present
in the section but AFTER the 0x0 and symbol CTOR_END. I’m no
ELF/startup expert but the code in __do_global_ctors_aux looks like it
relies on the symbol CTOR_END to figure out where to start. It then
works backwards until it finds FFFFFFFF. This would explain why our
constructors aren’t called.

In the working case (below), the symbol CTOR_END is towards the end of
the section and most/all of the necessary constructors preceed it. (I can’t
explain the extra items even in this case - maybe this is still not 100%
working???). By comparison to an objdump from another C++ application (e.g.
ddd) we see that the only 0x0 in the .ctors section is to be found at the
end.

Colin, does this give you anything to go on?
How exactly is the .ctors section built?
Should the CTOR_END symbol be right at the end of the section? Or is the
problem actually the NULL (0x0) in the middle of the table?

A (working?): file format elf32-i386

Contents of section .ctors:
80c7fc8 ffffffff 94230508 382c0508 18300508
80c7fd8 68420508 244f0508 7c540508 805f0508
80c7fe8 60840508 fc900508 48940508 f4a30508
80c7ff8 5cae0508 88c30508 14c40508 e4c80508
80c8008 6ce20508 dc060608 f41e0608 fc2e0608
80c8018 40340608 384c0608 004f0608 00000000
80c8028 b0520608 3c580608
Disassembly of section .ctors:

080c7fc8 <CTOR_LIST>:
80c7fc8: ff ff ff ff 94 23 05 08 38 2c 05 08 18 30 05 08
80c7fd8: 68 42 05 08 24 4f 05 08 7c 54 05 08 80 5f 05 08
80c7fe8: 60 84 05 08 fc 90 05 08 48 94 05 08 f4 a3 05 08
80c7ff8: 5c ae 05 08 88 c3 05 08 14 c4 05 08 e4 c8 05 08
80c8008: 6c e2 05 08 dc 06 06 08 f4 1e 06 08 fc 2e 06 08
80c8018: 40 34 06 08 38 4c 06 08 00 4f 06 08

080c8024 <CTOR_END>:
80c8024: 00 00 00 00 b0 52 06 08 3c 58 06 08

Rob Rutherford

“Robert Rutherford” <> ruzz@NoSpamPlease.ruzz.com> > wrote in message
news:agg22h$75r$> 1@inn.qnx.com> …
Thanks Colin.

I am currently trying to achieve this - or at least narrow it down to the
smallest set of differences that cause the problem. Of course all the
trivial cases work.

I was actually hoping that you might have some suggestions on
tools/tips/tricks to help diagnose this kind of problem - for example is
it
possible (using objdump or gdb or …) to actually have a look at all the
static initalisers/constructors that will be called prior to main().

Robert

“Colin Burgess” <> cburgess@qnx.com> > wrote in message
news:ages13$e48$> 1@nntp.qnx.com> …
I don’t suppose you can boil the two cases down into a small
testcase? :v)

Robert Rutherford <> ruzz@nospamplease.ruzz.com> > wrote:
I have a .cc file within a library which contains the following code:

static string testString = “TestString”;

The resulting library is statically linked with two different
executables
but using the same command-line options to qcc (and thus ld). Let’s
call
these executables A and B.

In executable A, the constructor for testString is (correctly) called
before
main().
In exectuable B, the constructor for testString is never called.


I have verified this in ddd.
Both executables use the objects/methods from the offending source
file.
The same thing happens with both the Dinkum and GCC libs.
We are using the release version of 6.2.

I guess it must be a link (ld) problem but this has me totally
stumped.
Can anyone offer any explanation or suggestion on how to track this
down?

Rob Rutherford
Ruzz Technology





\

cburgess@qnx.com




cburgess@qnx.com


cburgess@qnx.com

“Colin Burgess” <cburgess@qnx.com> wrote in message
news:agi19l$sbb$1@nntp.qnx.com

Colin Burgess <> cburgess@qnx.com> > wrote:

You also get the weird bug of the week award. :v)

And you both get the Dick Tracy award if you get this figured out.

It turns out that I’ve had to go to a customer site for the rest of this
week.
I won’t be able to post the requested info until Monday.

Maybe that means I’ll qualify for weird bug of the week award next week as
well.

Stay tuned.

Rob Rutherford

“Colin Burgess” <cburgess@qnx.com> wrote in message
news:agi19l$sbb$1@nntp.qnx.com

Colin Burgess <> cburgess@qnx.com> > wrote:
Yes, this is WRONG WRONG WRONG!

The ctors section is basically put together in the order it gets
presented to the linker.

So crtbeginC++.o and crtendC++.o

sorry, I didn’t finish my thought there.

You should have all crt files wrapping your objects. The only way
I can think of you getting the below result is if this is not the
case, hence the request for the -M, which will show the load order.
Actually, I’d love to see the link line as well.

You also get the weird bug of the week award. :v)

Can you generate a map file (-M) and grep for LOAD in it, and post that?

Robert Rutherford <> ruzz@nospamplease.ruzz.com> > wrote:
OK I’ve figured out that the key is the .ctors section within the ELF
file.
At least now I can quickly check whether things have worked by doing
“objdump -s -j .ctors”.

And I’ve found something else interesting:
In the failing file, all the correct constructors are actually listed
in the
.ctors section, but the symbol CTOR_END (and a 0x0 entry) seems to
be
placed prematurely early within the section.

For example, for executable B (failing) we have:

B (not working): file format elf32-i386

Contents of section .ctors:
809c794 ffffffff 10300508 143b0508 f45f0508
809c7a4 5c7a0508 10840508 00000000 c0870508
809c7b4 188d0508 44a20508 d0a20508 58bc0508
809c7c4 b8c00508 6cca0508 3ccf0508 acf30508
809c7d4 a8f40508
Disassembly of section .ctors:

0809c794 <CTOR_LIST>:
809c794: ff ff ff ff 10 30 05 08 14 3b 05 08 f4 5f 05 08
809c7a4: 5c 7a 05 08 10 84 05 08

0809c7ac <CTOR_END>:
809c7ac: 00 00 00 00 c0 87 05 08 18 8d 05 08 44 a2 05 08
809c7bc: d0 a2 05 08 58 bc 05 08 b8 c0 05 08 6c ca 05 08
809c7cc: 3c cf 05 08 ac f3 05 08 a8 f4 05 08

One particular constructor (group) that isn’t called (but should be)
has, in
this case, the address 0805a244. You will see that this is actually
present
in the section but AFTER the 0x0 and symbol CTOR_END. I’m no
ELF/startup expert but the code in __do_global_ctors_aux looks like it
relies on the symbol CTOR_END to figure out where to start. It then
works backwards until it finds FFFFFFFF. This would explain why our
constructors aren’t called.

In the working case (below), the symbol CTOR_END is towards the end
of
the section and most/all of the necessary constructors preceed it. (I
can’t
explain the extra items even in this case - maybe this is still not
100%
working???). By comparison to an objdump from another C++ application
(e.g.
ddd) we see that the only 0x0 in the .ctors section is to be found at
the
end.

Colin, does this give you anything to go on?
How exactly is the .ctors section built?
Should the CTOR_END symbol be right at the end of the section? Or
is the
problem actually the NULL (0x0) in the middle of the table?

A (working?): file format elf32-i386

Contents of section .ctors:
80c7fc8 ffffffff 94230508 382c0508 18300508
80c7fd8 68420508 244f0508 7c540508 805f0508
80c7fe8 60840508 fc900508 48940508 f4a30508
80c7ff8 5cae0508 88c30508 14c40508 e4c80508
80c8008 6ce20508 dc060608 f41e0608 fc2e0608
80c8018 40340608 384c0608 004f0608 00000000
80c8028 b0520608 3c580608
Disassembly of section .ctors:

080c7fc8 <CTOR_LIST>:
80c7fc8: ff ff ff ff 94 23 05 08 38 2c 05 08 18 30 05 08
80c7fd8: 68 42 05 08 24 4f 05 08 7c 54 05 08 80 5f 05 08
80c7fe8: 60 84 05 08 fc 90 05 08 48 94 05 08 f4 a3 05 08
80c7ff8: 5c ae 05 08 88 c3 05 08 14 c4 05 08 e4 c8 05 08
80c8008: 6c e2 05 08 dc 06 06 08 f4 1e 06 08 fc 2e 06 08
80c8018: 40 34 06 08 38 4c 06 08 00 4f 06 08

080c8024 <CTOR_END>:
80c8024: 00 00 00 00 b0 52 06 08 3c 58 06 08

Rob Rutherford

“Robert Rutherford” <> ruzz@NoSpamPlease.ruzz.com> > wrote in message
news:agg22h$75r$> 1@inn.qnx.com> …
Thanks Colin.

I am currently trying to achieve this - or at least narrow it down to
the
smallest set of differences that cause the problem. Of course all the
trivial cases work.

I was actually hoping that you might have some suggestions on
tools/tips/tricks to help diagnose this kind of problem - for example
is
it
possible (using objdump or gdb or …) to actually have a look at all
the
static initalisers/constructors that will be called prior to main().

Robert

“Colin Burgess” <> cburgess@qnx.com> > wrote in message
news:ages13$e48$> 1@nntp.qnx.com> …
I don’t suppose you can boil the two cases down into a small
testcase? :v)

Robert Rutherford <> ruzz@nospamplease.ruzz.com> > wrote:
I have a .cc file within a library which contains the following
code:

static string testString = “TestString”;

The resulting library is statically linked with two different
executables
but using the same command-line options to qcc (and thus ld).
Let’s
call
these executables A and B.

In executable A, the constructor for testString is (correctly)
called
before
main().
In exectuable B, the constructor for testString is never called.


I have verified this in ddd.
Both executables use the objects/methods from the offending source
file.
The same thing happens with both the Dinkum and GCC libs.
We are using the release version of 6.2.

I guess it must be a link (ld) problem but this has me totally
stumped.
Can anyone offer any explanation or suggestion on how to track
this
down?

Rob Rutherford
Ruzz Technology





\

cburgess@qnx.com





\

cburgess@qnx.com

\

cburgess@qnx.com

Ok I managed to get to the office on the way to the airport. Here is the
requested information:

Here is the output of “grep LOAD displog.map”

LOAD /x86/lib/crt1.o
LOAD /x86/lib/crti.o
LOAD /usr/lib/gcc-lib/ntox86/2.95.3/crtbeginC++.o
LOAD displog.o
LOAD …/…/lib/debug.lib
LOAD …/…/lib/global.lib
LOAD …/…/lib/logmem.lib
LOAD …/…/lib/shmem.lib
LOAD …/…/lib/timecode_posix.lib
LOAD …/…/lib/log_memonly.lib
LOAD …/…/lib/ipc.lib
LOAD …/…/lib/dsapi.lib
LOAD …/…/lib/app.lib
LOAD …/…/lib/ReplyStatus.lib
LOAD …/…/lib/stringutils.lib
LOAD /x86/lib/libcpp.so
LOAD /x86/lib/libm.so
LOAD /usr/lib/gcc-lib/ntox86/2.95.3/exceptions/libgcc.a
LOAD /x86/lib/libc.so
LOAD /x86/lib/libc.a
LOAD /usr/lib/gcc-lib/ntox86/2.95.3/exceptions/libgcc.a
LOAD /usr/lib/gcc-lib/ntox86/2.95.3/crtendC++.o
LOAD /x86/lib/crtn.o

Here is the corresponding link line:

$ make displog
cc -V gcc_ntox86_cpp -D DINKUMLIBS -gdwarf-2 -lang-c++ -M -Wl,-( -L
…/…/lib -Wl,–warn-constructors displog.o …/…/lib/debug.lib
…/…/lib/global.lib …/…/lib/logmem.lib …/…/lib/shmem.lib
…/…/lib/timecode_posix.lib
…/…/lib/log_memonly.lib …/…/lib/ipc.lib …/…/lib/dsapi.lib
…/…/lib/app.lib …/…/lib/ReplyStatus.lib …/…/lib/stringutils.lib -o
displog

“Robert Rutherford” <ruzz@ruzz.com> wrote in message
news:agiec9$3o2$1@inn.qnx.com

It turns out that I’ve had to go to a customer site for the rest of this
week.
I won’t be able to post the requested info until Monday.

Maybe that means I’ll qualify for weird bug of the week award next week as
well.

Stay tuned.

Rob Rutherford

“Colin Burgess” <> cburgess@qnx.com> > wrote in message
news:agi19l$sbb$> 1@nntp.qnx.com> …
Colin Burgess <> cburgess@qnx.com> > wrote:
Yes, this is WRONG WRONG WRONG!

The ctors section is basically put together in the order it gets
presented to the linker.

So crtbeginC++.o and crtendC++.o

sorry, I didn’t finish my thought there.

You should have all crt files wrapping your objects. The only way
I can think of you getting the below result is if this is not the
case, hence the request for the -M, which will show the load order.
Actually, I’d love to see the link line as well.

You also get the weird bug of the week award. :v)

Can you generate a map file (-M) and grep for LOAD in it, and post
that?

Robert Rutherford <> ruzz@nospamplease.ruzz.com> > wrote:
OK I’ve figured out that the key is the .ctors section within the ELF
file.
At least now I can quickly check whether things have worked by doing
“objdump -s -j .ctors”.

And I’ve found something else interesting:
In the failing file, all the correct constructors are actually listed
in the
.ctors section, but the symbol CTOR_END (and a 0x0 entry) seems
to
be
placed prematurely early within the section.

For example, for executable B (failing) we have:

B (not working): file format elf32-i386

Contents of section .ctors:
809c794 ffffffff 10300508 143b0508 f45f0508
809c7a4 5c7a0508 10840508 00000000 c0870508
809c7b4 188d0508 44a20508 d0a20508 58bc0508
809c7c4 b8c00508 6cca0508 3ccf0508 acf30508
809c7d4 a8f40508
Disassembly of section .ctors:

0809c794 <CTOR_LIST>:
809c794: ff ff ff ff 10 30 05 08 14 3b 05 08 f4 5f 05 08
809c7a4: 5c 7a 05 08 10 84 05 08

0809c7ac <CTOR_END>:
809c7ac: 00 00 00 00 c0 87 05 08 18 8d 05 08 44 a2 05 08
809c7bc: d0 a2 05 08 58 bc 05 08 b8 c0 05 08 6c ca 05 08
809c7cc: 3c cf 05 08 ac f3 05 08 a8 f4 05 08

One particular constructor (group) that isn’t called (but should be)
has, in
this case, the address 0805a244. You will see that this is actually
present
in the section but AFTER the 0x0 and symbol CTOR_END. I’m no
ELF/startup expert but the code in __do_global_ctors_aux looks like
it
relies on the symbol CTOR_END to figure out where to start. It
then
works backwards until it finds FFFFFFFF. This would explain why our
constructors aren’t called.

In the working case (below), the symbol CTOR_END is towards the
end
of
the section and most/all of the necessary constructors preceed it. (I
can’t
explain the extra items even in this case - maybe this is still not
100%
working???). By comparison to an objdump from another C++ application
(e.g.
ddd) we see that the only 0x0 in the .ctors section is to be found at
the
end.

Colin, does this give you anything to go on?
How exactly is the .ctors section built?
Should the CTOR_END symbol be right at the end of the section? Or
is the
problem actually the NULL (0x0) in the middle of the table?

A (working?): file format elf32-i386

Contents of section .ctors:
80c7fc8 ffffffff 94230508 382c0508 18300508
80c7fd8 68420508 244f0508 7c540508 805f0508
80c7fe8 60840508 fc900508 48940508 f4a30508
80c7ff8 5cae0508 88c30508 14c40508 e4c80508
80c8008 6ce20508 dc060608 f41e0608 fc2e0608
80c8018 40340608 384c0608 004f0608 00000000
80c8028 b0520608 3c580608
Disassembly of section .ctors:

080c7fc8 <CTOR_LIST>:
80c7fc8: ff ff ff ff 94 23 05 08 38 2c 05 08 18 30 05 08
80c7fd8: 68 42 05 08 24 4f 05 08 7c 54 05 08 80 5f 05 08
80c7fe8: 60 84 05 08 fc 90 05 08 48 94 05 08 f4 a3 05 08
80c7ff8: 5c ae 05 08 88 c3 05 08 14 c4 05 08 e4 c8 05 08
80c8008: 6c e2 05 08 dc 06 06 08 f4 1e 06 08 fc 2e 06 08
80c8018: 40 34 06 08 38 4c 06 08 00 4f 06 08

080c8024 <CTOR_END>:
80c8024: 00 00 00 00 b0 52 06 08 3c 58 06 08

Rob Rutherford

“Robert Rutherford” <> ruzz@NoSpamPlease.ruzz.com> > wrote in message
news:agg22h$75r$> 1@inn.qnx.com> …
Thanks Colin.

I am currently trying to achieve this - or at least narrow it down
to
the
smallest set of differences that cause the problem. Of course all
the
trivial cases work.

I was actually hoping that you might have some suggestions on
tools/tips/tricks to help diagnose this kind of problem - for
example
is
it
possible (using objdump or gdb or …) to actually have a look at
all
the
static initalisers/constructors that will be called prior to main().

Robert

“Colin Burgess” <> cburgess@qnx.com> > wrote in message
news:ages13$e48$> 1@nntp.qnx.com> …
I don’t suppose you can boil the two cases down into a small
testcase? :v)

Robert Rutherford <> ruzz@nospamplease.ruzz.com> > wrote:
I have a .cc file within a library which contains the following
code:

static string testString = “TestString”;

The resulting library is statically linked with two different
executables
but using the same command-line options to qcc (and thus ld).
Let’s
call
these executables A and B.

In executable A, the constructor for testString is (correctly)
called
before
main().
In exectuable B, the constructor for testString is never called.


I have verified this in ddd.
Both executables use the objects/methods from the offending
source
file.
The same thing happens with both the Dinkum and GCC libs.
We are using the release version of 6.2.

I guess it must be a link (ld) problem but this has me totally
stumped.
Can anyone offer any explanation or suggestion on how to track
this
down?

Rob Rutherford
Ruzz Technology





\

cburgess@qnx.com





\

cburgess@qnx.com

\

cburgess@qnx.com

Eureka!

You are using the -( operator to start a lib search group. But you’re
forgetting the -) to end it!!!

I finally managed to reproduce this by having a main that needed something
in lib2 which needed something in lib1

qcc -o main main.cc -Wl,-( lib1.a lib2.a

shows the same ctors screwup

qcc -o main main.cc -Wl,-( lib1.a lib2.a -Wl,-)

doesn’t.

So next time be a good boy and finish what you start! ;v)

Colin

Robert Rutherford <ruzz@nospamplease.ruzz.com> wrote:

Ok I managed to get to the office on the way to the airport. Here is the
requested information:

Here is the output of “grep LOAD displog.map”

LOAD /x86/lib/crt1.o
LOAD /x86/lib/crti.o
LOAD /usr/lib/gcc-lib/ntox86/2.95.3/crtbeginC++.o
LOAD displog.o
LOAD …/…/lib/debug.lib
LOAD …/…/lib/global.lib
LOAD …/…/lib/logmem.lib
LOAD …/…/lib/shmem.lib
LOAD …/…/lib/timecode_posix.lib
LOAD …/…/lib/log_memonly.lib
LOAD …/…/lib/ipc.lib
LOAD …/…/lib/dsapi.lib
LOAD …/…/lib/app.lib
LOAD …/…/lib/ReplyStatus.lib
LOAD …/…/lib/stringutils.lib
LOAD /x86/lib/libcpp.so
LOAD /x86/lib/libm.so
LOAD /usr/lib/gcc-lib/ntox86/2.95.3/exceptions/libgcc.a
LOAD /x86/lib/libc.so
LOAD /x86/lib/libc.a
LOAD /usr/lib/gcc-lib/ntox86/2.95.3/exceptions/libgcc.a
LOAD /usr/lib/gcc-lib/ntox86/2.95.3/crtendC++.o
LOAD /x86/lib/crtn.o

Here is the corresponding link line:

$ make displog
cc -V gcc_ntox86_cpp -D DINKUMLIBS -gdwarf-2 -lang-c++ -M -Wl,-( -L
…/…/lib -Wl,–warn-constructors displog.o …/…/lib/debug.lib
…/…/lib/global.lib …/…/lib/logmem.lib …/…/lib/shmem.lib
…/…/lib/timecode_posix.lib
…/…/lib/log_memonly.lib …/…/lib/ipc.lib …/…/lib/dsapi.lib
…/…/lib/app.lib …/…/lib/ReplyStatus.lib …/…/lib/stringutils.lib -o
displog

“Robert Rutherford” <> ruzz@ruzz.com> > wrote in message
news:agiec9$3o2$> 1@inn.qnx.com> …
It turns out that I’ve had to go to a customer site for the rest of this
week.
I won’t be able to post the requested info until Monday.

Maybe that means I’ll qualify for weird bug of the week award next week as
well.

Stay tuned.

Rob Rutherford

“Colin Burgess” <> cburgess@qnx.com> > wrote in message
news:agi19l$sbb$> 1@nntp.qnx.com> …
Colin Burgess <> cburgess@qnx.com> > wrote:
Yes, this is WRONG WRONG WRONG!

The ctors section is basically put together in the order it gets
presented to the linker.

So crtbeginC++.o and crtendC++.o

sorry, I didn’t finish my thought there.

You should have all crt files wrapping your objects. The only way
I can think of you getting the below result is if this is not the
case, hence the request for the -M, which will show the load order.
Actually, I’d love to see the link line as well.

You also get the weird bug of the week award. :v)

Can you generate a map file (-M) and grep for LOAD in it, and post
that?

Robert Rutherford <> ruzz@nospamplease.ruzz.com> > wrote:
OK I’ve figured out that the key is the .ctors section within the ELF
file.
At least now I can quickly check whether things have worked by doing
“objdump -s -j .ctors”.

And I’ve found something else interesting:
In the failing file, all the correct constructors are actually listed
in the
.ctors section, but the symbol CTOR_END (and a 0x0 entry) seems
to
be
placed prematurely early within the section.

For example, for executable B (failing) we have:

B (not working): file format elf32-i386

Contents of section .ctors:
809c794 ffffffff 10300508 143b0508 f45f0508
809c7a4 5c7a0508 10840508 00000000 c0870508
809c7b4 188d0508 44a20508 d0a20508 58bc0508
809c7c4 b8c00508 6cca0508 3ccf0508 acf30508
809c7d4 a8f40508
Disassembly of section .ctors:

0809c794 <CTOR_LIST>:
809c794: ff ff ff ff 10 30 05 08 14 3b 05 08 f4 5f 05 08
809c7a4: 5c 7a 05 08 10 84 05 08

0809c7ac <CTOR_END>:
809c7ac: 00 00 00 00 c0 87 05 08 18 8d 05 08 44 a2 05 08
809c7bc: d0 a2 05 08 58 bc 05 08 b8 c0 05 08 6c ca 05 08
809c7cc: 3c cf 05 08 ac f3 05 08 a8 f4 05 08

One particular constructor (group) that isn’t called (but should be)
has, in
this case, the address 0805a244. You will see that this is actually
present
in the section but AFTER the 0x0 and symbol CTOR_END. I’m no
ELF/startup expert but the code in __do_global_ctors_aux looks like
it
relies on the symbol CTOR_END to figure out where to start. It
then
works backwards until it finds FFFFFFFF. This would explain why our
constructors aren’t called.

In the working case (below), the symbol CTOR_END is towards the
end
of
the section and most/all of the necessary constructors preceed it. (I
can’t
explain the extra items even in this case - maybe this is still not
100%
working???). By comparison to an objdump from another C++ application
(e.g.
ddd) we see that the only 0x0 in the .ctors section is to be found at
the
end.

Colin, does this give you anything to go on?
How exactly is the .ctors section built?
Should the CTOR_END symbol be right at the end of the section? Or
is the
problem actually the NULL (0x0) in the middle of the table?

A (working?): file format elf32-i386

Contents of section .ctors:
80c7fc8 ffffffff 94230508 382c0508 18300508
80c7fd8 68420508 244f0508 7c540508 805f0508
80c7fe8 60840508 fc900508 48940508 f4a30508
80c7ff8 5cae0508 88c30508 14c40508 e4c80508
80c8008 6ce20508 dc060608 f41e0608 fc2e0608
80c8018 40340608 384c0608 004f0608 00000000
80c8028 b0520608 3c580608
Disassembly of section .ctors:

080c7fc8 <CTOR_LIST>:
80c7fc8: ff ff ff ff 94 23 05 08 38 2c 05 08 18 30 05 08
80c7fd8: 68 42 05 08 24 4f 05 08 7c 54 05 08 80 5f 05 08
80c7fe8: 60 84 05 08 fc 90 05 08 48 94 05 08 f4 a3 05 08
80c7ff8: 5c ae 05 08 88 c3 05 08 14 c4 05 08 e4 c8 05 08
80c8008: 6c e2 05 08 dc 06 06 08 f4 1e 06 08 fc 2e 06 08
80c8018: 40 34 06 08 38 4c 06 08 00 4f 06 08

080c8024 <CTOR_END>:
80c8024: 00 00 00 00 b0 52 06 08 3c 58 06 08

Rob Rutherford

“Robert Rutherford” <> ruzz@NoSpamPlease.ruzz.com> > wrote in message
news:agg22h$75r$> 1@inn.qnx.com> …
Thanks Colin.

I am currently trying to achieve this - or at least narrow it down
to
the
smallest set of differences that cause the problem. Of course all
the
trivial cases work.

I was actually hoping that you might have some suggestions on
tools/tips/tricks to help diagnose this kind of problem - for
example
is
it
possible (using objdump or gdb or …) to actually have a look at
all
the
static initalisers/constructors that will be called prior to main().

Robert

“Colin Burgess” <> cburgess@qnx.com> > wrote in message
news:ages13$e48$> 1@nntp.qnx.com> …
I don’t suppose you can boil the two cases down into a small
testcase? :v)

Robert Rutherford <> ruzz@nospamplease.ruzz.com> > wrote:
I have a .cc file within a library which contains the following
code:

static string testString = “TestString”;

The resulting library is statically linked with two different
executables
but using the same command-line options to qcc (and thus ld).
Let’s
call
these executables A and B.

In executable A, the constructor for testString is (correctly)
called
before
main().
In exectuable B, the constructor for testString is never called.


I have verified this in ddd.
Both executables use the objects/methods from the offending
source
file.
The same thing happens with both the Dinkum and GCC libs.
We are using the release version of 6.2.

I guess it must be a link (ld) problem but this has me totally
stumped.
Can anyone offer any explanation or suggestion on how to track
this
down?

Rob Rutherford
Ruzz Technology





\

cburgess@qnx.com





\

cburgess@qnx.com

\

cburgess@qnx.com


cburgess@qnx.com

Thanks Colin - I knew you’d get to the bottom of it.

So does this count as a ld bug? I thought leaving out the closing -) was (at
least theoretically) allowed? Anyway at least now we know how to fix it.

Now I just have to figure out how to modify our Makefiles to add the -) at
the end :slight_smile:

I guess this just adds to the quantity of beer that we owe you. Good thing
there’s no sign of a QNX Conference.

Robert


“Colin Burgess” <cburgess@qnx.com> wrote in message
news:agk6na$j64$1@nntp.qnx.com

Eureka!

You are using the -( operator to start a lib search group. But you’re
forgetting the -) to end it!!!

I finally managed to reproduce this by having a main that needed something
in lib2 which needed something in lib1

qcc -o main main.cc -Wl,-( lib1.a lib2.a

shows the same ctors screwup

qcc -o main main.cc -Wl,-( lib1.a lib2.a -Wl,-)

doesn’t.

So next time be a good boy and finish what you start! ;v)

Colin

Robert Rutherford <> ruzz@nospamplease.ruzz.com> > wrote:
Ok I managed to get to the office on the way to the airport. Here is the
requested information:

Here is the output of “grep LOAD displog.map”

LOAD /x86/lib/crt1.o
LOAD /x86/lib/crti.o
LOAD /usr/lib/gcc-lib/ntox86/2.95.3/crtbeginC++.o
LOAD displog.o
LOAD …/…/lib/debug.lib
LOAD …/…/lib/global.lib
LOAD …/…/lib/logmem.lib
LOAD …/…/lib/shmem.lib
LOAD …/…/lib/timecode_posix.lib
LOAD …/…/lib/log_memonly.lib
LOAD …/…/lib/ipc.lib
LOAD …/…/lib/dsapi.lib
LOAD …/…/lib/app.lib
LOAD …/…/lib/ReplyStatus.lib
LOAD …/…/lib/stringutils.lib
LOAD /x86/lib/libcpp.so
LOAD /x86/lib/libm.so
LOAD /usr/lib/gcc-lib/ntox86/2.95.3/exceptions/libgcc.a
LOAD /x86/lib/libc.so
LOAD /x86/lib/libc.a
LOAD /usr/lib/gcc-lib/ntox86/2.95.3/exceptions/libgcc.a
LOAD /usr/lib/gcc-lib/ntox86/2.95.3/crtendC++.o
LOAD /x86/lib/crtn.o

Here is the corresponding link line:

$ make displog
cc -V gcc_ntox86_cpp -D
DINKUMLIBS_ -gdwarf-2 -lang-c++ -M -Wl,-( -L
…/…/lib -Wl,–warn-constructors displog.o …/…/lib/debug.lib
…/…/lib/global.lib …/…/lib/logmem.lib …/…/lib/shmem.lib
…/…/lib/timecode_posix.lib
…/…/lib/log_memonly.lib …/…/lib/ipc.lib …/…/lib/dsapi.lib
…/…/lib/app.lib …/…/lib/ReplyStatus.lib
…/…/lib/stringutils.lib -o
displog

“Robert Rutherford” <> ruzz@ruzz.com> > wrote in message
news:agiec9$3o2$> 1@inn.qnx.com> …
It turns out that I’ve had to go to a customer site for the rest of
this
week.
I won’t be able to post the requested info until Monday.

Maybe that means I’ll qualify for weird bug of the week award next week
as
well.

Stay tuned.

Rob Rutherford

“Colin Burgess” <> cburgess@qnx.com> > wrote in message
news:agi19l$sbb$> 1@nntp.qnx.com> …
Colin Burgess <> cburgess@qnx.com> > wrote:
Yes, this is WRONG WRONG WRONG!

The ctors section is basically put together in the order it gets
presented to the linker.

So crtbeginC++.o and crtendC++.o

sorry, I didn’t finish my thought there.

You should have all crt files wrapping your objects. The only way
I can think of you getting the below result is if this is not the
case, hence the request for the -M, which will show the load order.
Actually, I’d love to see the link line as well.

You also get the weird bug of the week award. :v)

Can you generate a map file (-M) and grep for LOAD in it, and post
that?

Robert Rutherford <> ruzz@nospamplease.ruzz.com> > wrote:
OK I’ve figured out that the key is the .ctors section within the
ELF
file.
At least now I can quickly check whether things have worked by
doing
“objdump -s -j .ctors”.

And I’ve found something else interesting:
In the failing file, all the correct constructors are actually
listed
in the
.ctors section, but the symbol CTOR_END (and a 0x0 entry)
seems
to
be
placed prematurely early within the section.

For example, for executable B (failing) we have:

B (not working): file format elf32-i386

Contents of section .ctors:
809c794 ffffffff 10300508 143b0508 f45f0508
809c7a4 5c7a0508 10840508 00000000 c0870508
809c7b4 188d0508 44a20508 d0a20508 58bc0508
809c7c4 b8c00508 6cca0508 3ccf0508 acf30508
809c7d4 a8f40508
Disassembly of section .ctors:

0809c794 <CTOR_LIST>:
809c794: ff ff ff ff 10 30 05 08 14 3b 05 08 f4 5f 05 08
809c7a4: 5c 7a 05 08 10 84 05 08

0809c7ac <CTOR_END>:
809c7ac: 00 00 00 00 c0 87 05 08 18 8d 05 08 44 a2 05 08
809c7bc: d0 a2 05 08 58 bc 05 08 b8 c0 05 08 6c ca 05 08
809c7cc: 3c cf 05 08 ac f3 05 08 a8 f4 05 08

One particular constructor (group) that isn’t called (but should
be)
has, in
this case, the address 0805a244. You will see that this is
actually
present
in the section but AFTER the 0x0 and symbol CTOR_END. I’m no
ELF/startup expert but the code in __do_global_ctors_aux looks
like
it
relies on the symbol CTOR_END to figure out where to start. It
then
works backwards until it finds FFFFFFFF. This would explain why
our
constructors aren’t called.

In the working case (below), the symbol CTOR_END is towards
the
end
of
the section and most/all of the necessary constructors preceed it.
(I
can’t
explain the extra items even in this case - maybe this is still
not
100%
working???). By comparison to an objdump from another C++
application
(e.g.
ddd) we see that the only 0x0 in the .ctors section is to be found
at
the
end.

Colin, does this give you anything to go on?
How exactly is the .ctors section built?
Should the CTOR_END symbol be right at the end of the section?
Or
is the
problem actually the NULL (0x0) in the middle of the table?

A (working?): file format elf32-i386

Contents of section .ctors:
80c7fc8 ffffffff 94230508 382c0508 18300508
80c7fd8 68420508 244f0508 7c540508 805f0508
80c7fe8 60840508 fc900508 48940508 f4a30508
80c7ff8 5cae0508 88c30508 14c40508 e4c80508
80c8008 6ce20508 dc060608 f41e0608 fc2e0608
80c8018 40340608 384c0608 004f0608 00000000
80c8028 b0520608 3c580608
Disassembly of section .ctors:

080c7fc8 <CTOR_LIST>:
80c7fc8: ff ff ff ff 94 23 05 08 38 2c 05 08 18 30 05 08
80c7fd8: 68 42 05 08 24 4f 05 08 7c 54 05 08 80 5f 05 08
80c7fe8: 60 84 05 08 fc 90 05 08 48 94 05 08 f4 a3 05 08
80c7ff8: 5c ae 05 08 88 c3 05 08 14 c4 05 08 e4 c8 05 08
80c8008: 6c e2 05 08 dc 06 06 08 f4 1e 06 08 fc 2e 06 08
80c8018: 40 34 06 08 38 4c 06 08 00 4f 06 08

080c8024 <CTOR_END>:
80c8024: 00 00 00 00 b0 52 06 08 3c 58 06 08

Rob Rutherford

“Robert Rutherford” <> ruzz@NoSpamPlease.ruzz.com> > wrote in message
news:agg22h$75r$> 1@inn.qnx.com> …
Thanks Colin.

I am currently trying to achieve this - or at least narrow it
down
to
the
smallest set of differences that cause the problem. Of course all
the
trivial cases work.

I was actually hoping that you might have some suggestions on
tools/tips/tricks to help diagnose this kind of problem - for
example
is
it
possible (using objdump or gdb or …) to actually have a look at
all
the
static initalisers/constructors that will be called prior to
main().

Robert

“Colin Burgess” <> cburgess@qnx.com> > wrote in message
news:ages13$e48$> 1@nntp.qnx.com> …
I don’t suppose you can boil the two cases down into a small
testcase? :v)

Robert Rutherford <> ruzz@nospamplease.ruzz.com> > wrote:
I have a .cc file within a library which contains the
following
code:

static string testString = “TestString”;

The resulting library is statically linked with two different
executables
but using the same command-line options to qcc (and thus ld).
Let’s
call
these executables A and B.

In executable A, the constructor for testString is
(correctly)
called
before
main().
In exectuable B, the constructor for testString is never
called.


I have verified this in ddd.
Both executables use the objects/methods from the offending
source
file.
The same thing happens with both the Dinkum and GCC libs.
We are using the release version of 6.2.

I guess it must be a link (ld) problem but this has me
totally
stumped.
Can anyone offer any explanation or suggestion on how to
track
this
down?

Rob Rutherford
Ruzz Technology





\

cburgess@qnx.com





\

cburgess@qnx.com

\

cburgess@qnx.com





\

cburgess@qnx.com

Robert Rutherford <ruzz@ruzz.com> wrote:

Thanks Colin - I knew you’d get to the bottom of it.

So does this count as a ld bug? I thought leaving out the closing -) was (at
least theoretically) allowed? Anyway at least now we know how to fix it.

I don’t think it’s really a bug. The CTORS and DTORS stuff very specifically
relies on the order the object files and symbols are loaded to get things
right - when you use the grouping symbols, then the order may not be
done in the command line order.

Now I just have to figure out how to modify our Makefiles to add the -) at
the end > :slight_smile:

Maybe it’s just easier to add them in the right order, and multiple
times if necessary? ;v)

I guess this just adds to the quantity of beer that we owe you. Good thing
there’s no sign of a QNX Conference.

Ah, dreams of a cold room full of beer, with “Property of Colin Burgess”
on the door… |v)


cburgess@qnx.com