Bug #55345 mysql_library_init causes segfault if executed after calling mysql_library_end
Submitted: 18 Jul 2010 12:46 Modified: 2 Sep 2010 15:57
Reporter: Oleg Sidorkin Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: C API (client library) Severity:S2 (Serious)
Version:5.5.5-m3, 5.6.99 OS:Any (FreeBSD, Linux)
Assigned to: Christopher Powers CPU Architecture:Any
Tags: mysql_library_init, regression

[18 Jul 2010 12:46] Oleg Sidorkin
Description:
If you invoke mysql_library_init() after calling mysql_library_end() you are getting segmentation fault due to passig already freed object to the libpthread.

This happends due to my_thread_basic_global_init_done flag is set to 1 in  my_thread_basic_global_init(), but it is not reset to 0  my_thread_global_end() where corresponding objects are deleted. 
On the second call mysql_library_init() deleted objects are not created again because my_thread_basic_global_init_done is still 1.

Tested on FreeBSD 8.1

How to repeat:
compile with -lmysqlclient_r and run the following:

#include <my_global.h>
#include <mysql.h>

#include <stdio.h>

int main(void).
{
    if (mysql_library_init(0, 0, 0))
    {
        printf("could not initialize MySQL library\n");
        return 1;
    }

    mysql_library_end();

    if (mysql_library_init(0, 0, 0))
    {
        printf("could not initialize MySQL library\n");
        return 1;
    }

    mysql_library_end();

    return 0;
}

You will get core dump with the following backtrace:
(gdb) bt
#0  0x0000000801070328 in pthread_mutexattr_init () from /lib/libthr.so.3
#1  0x00000008006b18df in safe_mutex_init (mp=0x800adfa20, attr=0x800adfb70, file=0x800732828 "my_thr_init.c", line=217) at thr_mutex.c:62
#2  0x00000008006b0fe4 in my_thread_global_init () at mysql_thread.h:591
#3  0x00000008006a8d8c in my_basic_init () at my_init.c:103
#4  0x00000008006a8e08 in my_init () at my_init.c:146
#5  0x00000008006a7560 in mysql_server_init (argc=Variable "argc" is not available.
) at libmysql.c:126
#6  0x00000000004007bc in main () at main.c:16

Suggested fix:
add my_thread_basic_global_init_done= 0; to the end of my_thread_global_end() or create new function my_thread_basic_global_end() to be able to control objects lifecycle carefully.
[19 Jul 2010 7:05] Sveta Smirnova
Thank you for the report.

I can not repeat described behavior on FreeBSD6. You wrote you use FreeBSD8. Which connector/C binaries do you use? If you compiled connector yourself please send us configure options you used.
[19 Jul 2010 7:05] Susanne Ebrecht
Do you have similar problems by using MySQL server 5.1 instead 5.5?
[19 Jul 2010 9:10] Oleg Sidorkin
Sorry. I've completely forgot about build flags.
Both client and server were built with the following flags:

WITH_XCHARSET=all
BUILD_OPTIMIZED=yes
WITHOUT_INNODB=no
WITH_ARCHIEVE=yes
WITH_FEDERATED=yes
WITH_OPENSSL=yes
WITH_CHARSET=koi8r
WITH_FAST_MUTEXES=yes

MySQL 5.1 worked with the same flags with no problems
[19 Jul 2010 9:17] Sveta Smirnova
Thank you for the feedback.

You opened bug in Connector/C category while speaking about compiling server and using server. Do you really use Connector/C or is is regular C API libraries bundled with server?
[19 Jul 2010 10:30] Oleg Sidorkin
It is client library bug. Should I change the change the category of the bug?
[19 Jul 2010 11:20] Sveta Smirnova
Thank you for the feedback.

Verified as described. Connector/C is not affected.
[23 Aug 2010 1:43] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/116458

3190 Christopher Powers	2010-08-22
      Bug #55345, "mysql_library_init causes segfault if executed after calling mysql_library_end"
      
      my_thread_global_end() now sets mysql_thread_basic_global_init_done= 0
      to ensure destroyed mutexes are not reused.
      
      I verified that clearing this flag will not result in the redundant allocation
      of other resources allocated by my_thread_global_init() and
      my_thread_basic_global_init().
     @ mysys/my_thr_init.c
        Clear mysql_thread_basic_global_init_done flag at the end of my_thread_global_end()
[25 Aug 2010 9:21] Bugs System
Pushed into mysql-5.5 5.5.6-m3 (revid:alik@ibmvm-20100825092002-2yvkb3iwu43ycpnm) (version source revid:alik@ibmvm-20100825092002-2yvkb3iwu43ycpnm) (merge vers: 5.5.6-m3) (pib:20)
[27 Aug 2010 20:01] Paul DuBois
Noted in 5.5.6 changelog.

A call to mysql_library_init() following a call to
mysql_library_end() caused a client crash.

Setting report to Need Merge pending push to 5.6.x.
[30 Aug 2010 8:29] Bugs System
Pushed into mysql-trunk 5.6.1-m4 (revid:alik@sun.com-20100830082732-n2eyijnv86exc5ci) (version source revid:alik@sun.com-20100830082732-n2eyijnv86exc5ci) (merge vers: 5.6.1-m4) (pib:21)
[30 Aug 2010 8:33] Bugs System
Pushed into mysql-next-mr (revid:alik@sun.com-20100830082745-n6sh01wlwh3itasv) (version source revid:alik@sun.com-20100830082745-n6sh01wlwh3itasv) (pib:21)
[30 Aug 2010 15:07] Paul DuBois
Noted in 5.6.1 changelog.