views:

1125

answers:

3

I compiled 2 different binaries on the same GNU/Linux server using g++ version 4.2.3.

The first one uses:

GLIBC_2.0
GLIBC_2.2
GLIBC_2.1
GLIBCXX_3.4
GLIBC_2.1.3

The second one uses:

GLIBC_2.0
GLIBC_2.2
GLIBC_2.1
GLIBCXX_3.4.9
GLIBCXX_3.4
GLIBC_2.1.3

Why the second binary uses GLIBCXX_3.4.9 that is only available on libstdc++.so.6.0.9 and not in libstdc++.so.6.0.8

What is the new feature generated by g++ that require an ABI break and force the system to have GLIBCXX_3.4.9?

Is there a way to disable this new feature to not require GLIBCXX_3.4.9?

A: 

Well the first question is how did you generate the above list.
One would assume that the compiler is deterministic and thus link binaries in the same way.

I assume I got marked down for not answering the question directly but a comment would be nice. But I still think you have not provided the correct information and it would be nice to see the output of the command that shows your problem.

Assuming you used ldd:
You would get an output that looked like this:

lib<X>.so.<ver>  =>  /usr/lib/lib<X>.so.<verM>  (<Addr>)

But this is not the end of the story.
Trying doing an ls on the file it may be a symbolic link

> ls /usr/lilb/lib<X>.so.<verM>
lrwxrwxrwx 1 root root    <Date>  /usr/lib/lib<X>.so.<verM>  -> lib<X>.so.<verM>.<verm>.<verp>
Martin York
I removed my -1 since it seems to upset you :) I did it because your answer doesn't answer my questions, that's all. Don't take it bad!
acemtp
i think martin assumed that you took the same source, the same compiler and the same libstdc++ and compiled your program, getting different results. for that case, i think martin's answer is quite right.
Johannes Schaub - litb
+3  A: 

Since you asked for it, here are symbols having at least ABI version 3.4.9:

GLIBCXX_3.4.9 {

    _ZNSt6__norm15_List_node_base4hook*;
    _ZNSt6__norm15_List_node_base4swap*;
    _ZNSt6__norm15_List_node_base6unhookEv;
    _ZNSt6__norm15_List_node_base7reverseEv;
    _ZNSt6__norm15_List_node_base8transfer*;

    _ZNSo9_M_insertI[^g]*;
    _ZNSt13basic_ostreamIwSt11char_traitsIwEE9_M_insertI[^g]*;
    _ZNSi10_M_extractI[^g]*;
    _ZNSt13basic_istreamIwSt11char_traitsIwEE10_M_extractI[^g]*;

    _ZSt21__copy_streambufs_eofI[cw]St11char_traitsI[cw]EE[il]PSt15basic_streambuf*;

    _ZSt16__ostream_insert*;

    _ZN11__gnu_debug19_Safe_sequence_base12_M_get_mutexEv;
    _ZN11__gnu_debug19_Safe_iterator_base16_M_attach_singleEPNS_19_Safe_sequence_baseEb;
    _ZN11__gnu_debug19_Safe_iterator_base16_M_detach_singleEv;
    _ZN11__gnu_debug19_Safe_iterator_base12_M_get_mutexEv;

    _ZNKSt9bad_alloc4whatEv;
    _ZNKSt8bad_cast4whatEv;
    _ZNKSt10bad_typeid4whatEv;
    _ZNKSt13bad_exception4whatEv;

} GLIBCXX_3.4.8;

Run the file libstdc++-v3/config/abi/post/i386-linux-gnu/baseline_symbols.txt through c++filt, grepping for GLIBCXX_3.4.9 to make sense of those names (they look like wildcards only). I didn't do it because those names become quite long and nested. Later versions mostly include c++1x stuff. See the file libstdc++-v3/config/abi/pre/gnu.ver for the above. Read here about the VERSION linker script command.

Johannes Schaub - litb
I saw that "nm" gave the version of GLIBC after the symbol name so I found those used:_ZNSi10_M_extractIdEERSiRT_@@GLIBCXX_3.4.9_ZNSo9_M_insertIdEERSoT_@@GLIBCXX_3.4.9_ZSt16__ostream_insertIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_PKS3_i@@GLIBCXX_3.4.9Thanks
acemtp
+3  A: 

To find out which of the listed GLIBCXX_3.4.9 symbol(s) your binary actually depends on, do this:

readelf -s ./a.out | grep 'GLIBCXX_3\.4\.9' | c++filt

Once you know which symbols to look for, you can trace back to the object which needs them:

nm -A *.o | grep _ZN<whatever>

Finally, to tie this back to source, you can do:

objdump -dS foo.o

and see which code is referencing the 3.4.9 symbol(s).

Employed Russian
That is exactly what i was looking for! Thank you
acemtp