List:MySQL++« Previous MessageNext Message »
From:Andrey Ponomarenko Date:September 19 2011 5:37pm
Subject:Fixing 3.1.0 ABI breakage (Re: Problems with storein and template
queries)
View as plain text  
Hello,

On 03/18/2011 07:30 PM, Warren Young wrote:
> On Mar 18, 2011, at 8:59 AM, Florian Feldbauer wrote:
>
>> I have attached the modified source of tquery1.cpp.
> Okay, I've figured out what's going on.  I've been doing my tests against the svn
> version of MySQL++, not the 3.1.0 released version.  This bug was squished in svn back in
> August.
>
> The only thing holding me back from releasing 3.1.1 is that I want to fix the ABI
> breakage created by 3.1.0, reverting it to the 3.0.9 ABI.  If someone wants to give me a
> patch for this, 3.1.1 should shortly follow.

As shown in the compatibility report for mysql++ 3.0.9 and 3.1.0 
versions [1-2], there are 4 problems with ABI/binary compatibility:

   1. class ConnectionPool: exchange() and safe_grab() virtual functions
      were added at the middle position of v-table,
   2. class Comparable: removed _ZN10ComparableIN7mysqlpp4DateEED0Ev
      destructor from libmysqlpp.so,
   3. class DBDriver: increased the size from 1012 to 1056 bytes because
      of added pending_options_ and error_message_ fields,
   4. method DBDriver::set_option(): changed return value from
      std::string (class) to bool (intrinsic).

1) Lets consider the first problem. The ConnectionPool class is the leaf 
class (has no derived classes in libmysqlpp) with the default/copied 
constructor. This constructor was copied by old clients and will 
generate old v-table layout. The problem is that new library expects a 
new layout instead to call pure-virtual functions provided by the 
client. So, moving both new virtual functions to the end of class 
declaration after all old virtual functions will restore the positions 
of old virtual functions. However, added virtual functions still will 
not be presented in the old v-table generated by copied default 
constructor. So, in order to not to crash old clients, it should not be 
possible to call these functions through the calling of any symbols in 
the old library, i.e. you should call new symbols from the new symbols 
only. And it's, fortunately, true for mysql++ 3.1.0:

$> cd sources-3.1.0 && find . -name "*.cpp"| xargs grep 
"exchange\|safe_grab"

So, the only thing you need is to move both functions to the end of the 
class.

2) The second problem seems to be a false positive, because it is not 
possible to import this symbol from the libmysqlpp.so. The Comparable 
class has only default/copied constructor and therefore old clients will 
call an old copy of the removed symbol pointed by the old v-table copied 
by the constructor. The abi-compliance-checker tool will be improved in 
the future versions to not to report this false alarm.

3) The DBDriver class has an exported constructor and size of this class 
has been increased. Old size of this class will be hard-coded in the 
clients at the compile time and call of the new-version constructor will 
break the memory of neighboring objects on the stack or heap.

The layout of old DBDriver class:
// 4 bytes for v-table pointer
MYSQL mysql_; // 964 bytes
bool is_connected_; // 1 byte
// 3 bytes internal padding
OptionList applied_options_; // 40 bytes
// no tail padding

So, unfortunately, there is no place for pointer to hide added fields 
and the only way to move new fields away from the class is to create a 
derived class and move new fields to it or completely revert this change.

I recommend you to add reserved fields and virtual functions to the end 
of classes on the next ABI break in 4.0.

4) The return value of class type is passed through the first hidden 
parameter on the calling stack, unlike the intrinsic values, which are 
passed through the registers. So, there are two options here:
     - Change return value to a class derived from std::string with the 
"operator bool()" and "operator std::string()". This should be both 
binary and source backward-compatible,
     - Revert this change.

[1] 
http://linuxtesting.org/upstream-tracker/compat_reports/mysql++/3.0.9_to_3.1.0/abi_compat_report.html
[2] http://linuxtesting.org/upstream-tracker/versions/mysql++.html

-- 
Andrey Ponomarenko
Department for Operating Systems at ISPRAS
  web:    http://www.LinuxTesting.org
  mail:   aponomarenko@stripped


Thread
Re: Problems with storein and template queriesFlorian Feldbauer15 Mar
  • Re: Problems with storein and template queriesWarren Young15 Mar
    • Re: Problems with storein and template queriesWarren Young16 Mar
      • Re: Problems with storein and template queriesFlorian Feldbauer16 Mar
      • Re: Problems with storein and template queriesFlorian Feldbauer18 Mar
        • Re: Problems with storein and template queriesAdrian Cornish18 Mar
          • Re: Problems with storein and template queriesFlorian Feldbauer18 Mar
            • Re: Problems with storein and template queriesWarren Young18 Mar
              • Fixing 3.1.0 ABI breakage (Re: Problems with storein and templatequeries)Andrey Ponomarenko19 Sep