Bug #74620 mysql_embedded fails when linker selects wrong version of handler constructor
Submitted: 29 Oct 2014 16:07 Modified: 15 Dec 2014 15:35
Reporter: Dyre Tjeldvoll Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: Compiling Severity:S2 (Serious)
Version:5.7.5 OS:Any
Assigned to: CPU Architecture:Any

[29 Oct 2014 16:07] Dyre Tjeldvoll
Description:
One some platforms mysql_embedded will fail with:
main.mysql_embedded                      [ fail ]
        Test ended at 2014-10-29 16:09:26

CURRENT_TEST: main.mysql_embedded
mysql_embedded: /export/home/tmp/repo/mysql-trunk-19766312/sql/handler.h:2218: virtual handler::~handler(): Assertion `m_lock_type == 2' failed.
mysqltest: At line 60: command "$MYSQL_EMBEDDED --defaults-file=$special_config_file -e "SELECT 1"" failed

Output from before failure:
exec of '/export/home/tmp/build/mysql-trunk-19766312/libmysqld/examples/mysql_embedded --defaults-file=/export/home/tmp/build/mysql-trunk-19766312/mysql-test/var/tmp/my.mysql_embedded.cnf -e "SELECT 1"' failed, error: 6, status: 0, errno: 0

This was with 

Linux atum20.no.oracle.com 3.14.4-100.fc19.x86_64 #1 SMP Tue May 13 15:00:26 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux

g++ (GCC) 4.8.3 20140911 (Red Hat 4.8.3-7)
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Root cause appears to be that

/include/mysql/psi/psi.h

contains

#ifdef EMBEDDED_LIBRARY
#define DISABLE_ALL_PSI
#endif /* EMBEDDED_LIBRARY */

[...]

#ifdef DISABLE_ALL_PSI
[...]
#ifndef DISABLE_PSI_TABLE
#define DISABLE_PSI_TABLE
#endif
[...]
#ifndef DISABLE_PSI_TABLE
#define HAVE_PSI_TABLE_INTERFACE
#endif

So all code compiled with EMBEDDED_LIBRARY will not have
HAVE_PSI_TABLE_INTERFACE defined.

After

revno: 8146.1.13
committer: Marc Alff <marc.alff@oracle.com>
branch nick: mysql-trunk-wl7802
timestamp: Sat 2014-08-02 02:08:16 +0200
message:
  Fixed a build break when compiling without the performance schema

This implies that sizeof(handler) is different when compiling with EMBEDDED_LIBRARY. Since handler's constructor and destructor are defiened in handler.h each translation unit which includes handler.h will compile its own version of these member functions, and the code will be different in translation units where EMBEDDED_LIBRARY is defined.

This creates a problem as the mysql_embedded executable (used by mysql_embedded.test) is linked with archives that contain object files with both versions of the member functions.

If the linker chooses the "big handler" version of the constructor and the "small handler" version of the destructor the mysql_embedded test fails. Specifically, the assertion mentioned above is triggered because the constructor initializes m_lock_type at a different offset than the destructor reads it from.

How to repeat:
Run mysql_embedded on affected platform.

If the handler destructor is moved to handler.cc (which will be compiled with EMBEDDED_LIBRARY) and the constructor is moved to ha_innodb.cc (which isn't compiled with EMBEDDED_LIBRARY, but still linked into mysql_embedded) the mysql_embedded test fails predictably on all platforms.

Suggested fix:
1) Don't link mysql_embedded with non-embedded libraries (not feasible?)
2) Compile all required files with EMBEDDED_LIBRARY (will slow down compilation?)
3) Remove #ifdef or add dummy member to make handler have the same size in all places, or move the optional members to the end (fixes this problems, but could there be others?)
4) Move ctor and dtor to handler.cc (Perf impact? Does not fix other size-related issues)
[15 Dec 2014 15:35] Erlend Dahl
Fixed in 5.7.6.