lvc / abi-compliance-checker

A tool for checking backward API/ABI compatibility of a C/C++ library
https://lvc.github.io/abi-compliance-checker/
GNU Lesser General Public License v2.1
622 stars 76 forks source link

vtable reordering should be reported as High severity problem #66

Open asheplyakov opened 6 years ago

asheplyakov commented 6 years ago

Consider two binary incompatible versions of the class X: https://github.com/asheplyakov/libfoo/blob/v0/include/foo/foo.h#L11-L17 https://github.com/asheplyakov/libfoo/blob/v4/include/foo/foo.h#L22-L29

These classes have the following vtables:

$ vtable-dumper lib/libfoo.so.0 | sed -rne '/^Vtable for X/,$ {p}'
Vtable for X
_ZTV1X: 6 entries
0     (int (*)(...)) 0
8     (int (*)(...)) (& _ZTI1X)
16    (int (*)(...)) X::foo(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)
24    (int (*)(...)) X::bar(int)
32    (int (*)(...)) X::~X()
40    (int (*)(...)) X::~X()
$ vtable-dumper lib/libfoo.so.4 | sed -rne '/^Vtable for X/,$ {p}'
Vtable for X
_ZTV1X: 13 entries
0     (int (*)(...)) 0
8     (int (*)(...)) (& _ZTI1X)
16    (int (*)(...)) X::~X()
24    (int (*)(...)) X::~X()
32    (int (*)(...)) X::name[abi:cxx11]() const
40    (int (*)(...)) X::foo(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)
48    (int (*)(...)) X::bar(int)
56    (int (*)(...)) -0x00000000000008
64    (int (*)(...)) (& _ZTI1X)
72    (int (*)(...)) _ZThn8_N1X3fooERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
80    (int (*)(...)) _ZThn8_N1X3barEi
88    (int (*)(...)) _ZThn8_N1XD1Ev
96    (int (*)(...)) _ZThn8_N1XD0Ev

In particular the vtable of class X in libfoo.so.0 contains X::foo pointer at offset 16:

16 (int (*)(...)) X::foo(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)

On the other hand the vtable of class X in libfoo.so.4 contains X::~X() pointer at the same offset (16):

16 (int (*)(...)) X::~X()

However abi-compliance-checker declares these ABIs to be compatible. It correctly points out that the size of X's vtable changed, and warns that "Call of any method in this class may result in crash or incorrect behavior of applications." Indeed the app which expects to find &X::foo at offset 16 will definitely crash. Any reordering of vtable (except appending new entries) should be reported as a High severity problem.