GCC 8.3 and ABI check

Amitay Isaacs amitay at gmail.com
Tue Apr 9 04:28:44 UTC 2019


Hi,

With gcc 8.3.1 on fedora 29, ABI check keeps failing for various
conditions.  Noticed this when I tried building ctdb for the latest
master with developer build.

So I tried following experiments with talloc.

$ cd samba/lib/talloc
$ ./configure --abi-check
$ make
...
[26/28] Processing lib/talloc/bin/default/lib/talloc/libtalloc.so
libtalloc.so: symbol _talloc has changed - please update major version
    old_signature: void *(const void *, size_t)
    new_signature: <text variable, no debug info>
libtalloc.so: symbol _talloc_array has changed - please update major version
    old_signature: void *(const void *, size_t, unsigned int, const char *)
    new_signature: <text variable, no debug info>
...

Make complains for all the talloc symbols.  The new_signature field
contains "<text variable, no debug info>".   This means gdb is not
able to decode the signature of a symbol without debug information.

$ gdb bin/default/lib/talloc/libtalloc.so
(gdb) p _talloc
$1 = {<text variable, no debug info>} 0x5ca4 <_talloc>


Trying again with debug build..

$ CFLAGS="-g" ./configure --abi-check
$ make
...
[25/28] Processing lib/talloc/bin/default/lib/talloc/libtalloc.so
[26/28] Symlinking lib/talloc/bin/default/lib/talloc/libtalloc.so
[27/28] Symlinking
lib/talloc/bin/default/lib/talloc/libpytalloc-util.cpython-37m-x86-64-linux-gnu.so
[28/28] Processing
lib/talloc/bin/default/lib/talloc/libpytalloc-util.cpython-37m-x86-64-linux-gnu.so
...


No problem this time.  That's good.  Now try with optimization flags.


$ CFLAGS="-g -O2" ./configure --abi-check
$ make
...
[25/28] Processing lib/talloc/bin/default/lib/talloc/libtalloc.so
libtalloc.so: symbol talloc_version_minor has changed - please update
major version
    old_signature: int (void)
    new_signature: <text variable, no debug info>
...

This time make complains only for a symbol "talloc_version_minor".

$ gdb bin/default/lib/talloc/talloc.so
(gdb) p talloc_version_minor
$1 = {<text variable, no debug info>} 0x4340 <talloc_version_minor>
(gdb) p talloc_version_major
$2 = {int (void)} 0x4330 <talloc_version_major>

Clearly something is wrong.  Both the functions are defined
identically in talloc.c, so there should not be any difference related
to symbol information for both these functions.

Digging a bit deeper, here is the debug information from libtalloc.so

$ readelf --debug-dump=info bin/default/lib/talloc/libtalloc.so
...
 <1><10c20>: Abbrev Number: 104 (DW_TAG_subprogram)
    <10c21>   DW_AT_external    : 1
    <10c21>   DW_AT_name        : (indirect string, offset: 0xba7):
talloc_version_minor
    <10c25>   DW_AT_decl_file   : 1
    <10c26>   DW_AT_decl_line   : 335
    <10c28>   DW_AT_decl_column : 14
    <10c29>   DW_AT_prototyped  : 1
    <10c29>   DW_AT_type        : <0xcf>
 <1><10c2d>: Abbrev Number: 105 (DW_TAG_subprogram)
    <10c2e>   DW_AT_external    : 1
    <10c2e>   DW_AT_name        : (indirect string, offset: 0xf08):
talloc_version_major
    <10c32>   DW_AT_decl_file   : 1
    <10c33>   DW_AT_decl_line   : 330
    <10c35>   DW_AT_decl_column : 14
    <10c36>   DW_AT_prototyped  : 1
    <10c36>   DW_AT_type        : <0xcf>
    <10c3a>   DW_AT_inline      : 1     (inlined)
...

In the above output, there is a difference between the debug info for
both functions.  talloc_version_major is marked inlined, and
talloc_version_minor is not.   I cannot see any other difference
(Also, I don't know how to print more details of the debug info).

Comparing the similar output when compiled without optimize flag (-O2), you get

 <1><334f>: Abbrev Number: 59 (DW_TAG_subprogram)
    <3350>   DW_AT_external    : 1
    <3350>   DW_AT_name        : (indirect string, offset: 0xe28):
talloc_version_minor
    <3354>   DW_AT_decl_file   : 2
    <3355>   DW_AT_decl_line   : 335
    <3357>   DW_AT_decl_column : 14
    <3358>   DW_AT_prototyped  : 1
    <3358>   DW_AT_type        : <0xd8>
    <335c>   DW_AT_low_pc      : 0x3644
    <3364>   DW_AT_high_pc     : 0xb
    <336c>   DW_AT_frame_base  : 1 byte block: 9c       (DW_OP_call_frame_cfa)
    <336e>   DW_AT_GNU_all_call_sites: 1
 <1><336e>: Abbrev Number: 59 (DW_TAG_subprogram)
    <336f>   DW_AT_external    : 1
    <336f>   DW_AT_name        : (indirect string, offset: 0x1136):
talloc_version_major
    <3373>   DW_AT_decl_file   : 2
    <3374>   DW_AT_decl_line   : 330
    <3376>   DW_AT_decl_column : 14
    <3377>   DW_AT_prototyped  : 1
    <3377>   DW_AT_type        : <0xd8>
    <337b>   DW_AT_low_pc      : 0x3639
    <3383>   DW_AT_high_pc     : 0xb
    <338b>   DW_AT_frame_base  : 1 byte block: 9c       (DW_OP_call_frame_cfa)
    <338d>   DW_AT_GNU_all_call_sites: 1

Here, there is lot more information and gdb is able to resolve the
symbols correctly.

Issues:

1. We might have to add "-g" to build if abi_check is enabled.
(abi_check gets enabled for developer build).

2. The missing debug information from shared library when optimize
flags are used, seems like a bug in gcc.  Anyone has any other ideas
on how to confirm that?    To work around this problem we might need
to add "-g -O0" to CFLAGS if abi_check is enabled.

If you are on a different platform (different version of gcc), can you
check if abi check works?

$ cd samba/lib/talloc
$ ./configure --abi-check
$ make
$ CFLAGS="-O2" ./configure --abi-check
$ make

Any suggestions?

Amitay.



More information about the samba-technical mailing list