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