Bug #15846 libmysql: handle-leak in mysql_close with shared memory (fix supplied)
Submitted: 19 Dec 2005 1:36 Modified: 11 Apr 2006 3:27
Reporter: Armin Schöffmann (OCA) Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: Command-line Clients Severity:S2 (Serious)
Version:5.0.16/5.0.18 BK OS:Windows (WINXP_PROF_GER SP2)
Assigned to: Chad MILLER CPU Architecture:Any

[19 Dec 2005 1:36] Armin Schöffmann
Description:
with option 'MYSQL_PROTOCOL_MEMORY', mysql_real_connect(...) leaks 5 handles per successful connection.
mysql_close() doesn't free all allocated handles.

see below patch-suggestion
regards,armin.

How to repeat:
unsigned option;
my_bool reconnect;
MYSQL* hmysql

//-> remember handle count here

hmysql=mysql_init(NULL);

reconnect=true;
			
mysql_options(hmysql,MYSQL_OPT_RECONNECT,(char*)&reconnect);
option=MYSQL_PROTOCOL_MEMORY;
			mysql_options(hmysql,MYSQL_OPT_PROTOCOL,(char*)&option);
// -> count handles
mysql_real_connect(hmysql,server,psz_uid,psz_pwd,psz_db,0,NULL,CLIENT_MULTI_STATEMENTS);
mysql_close(hmysql);
// -> count handles again

Suggested fix:
viosocket.c
vio_close_shared_memory

effectively, only the first handle will be closed as the optimizer prevents the code from evaluating the complete expression.

Additionally, result(r) should track ALL close-operations.

int vio_close_shared_memory(Vio * vio)
{
[...]
 /*
     Close all handlers. UnmapViewOfFile and CloseHandle return non-zero
     result if they are success.
/*
    r= UnmapViewOfFile(vio->handle_map) || CloseHandle(vio->event_server_wrote) ||
       CloseHandle(vio->event_server_read) || CloseHandle(vio->event_client_wrote) ||
       CloseHandle(vio->event_client_read) || CloseHandle(vio->handle_file_map);
[...]
}

replace with:
    r= UnmapViewOfFile(vio->handle_map) && CloseHandle(vio->event_server_wrote) &&
       CloseHandle(vio->event_server_read) && CloseHandle(vio->event_client_wrote) &&
       CloseHandle(vio->event_client_read) && CloseHandle(vio->handle_file_map);

verified for debug-build (5.0.16)
[19 Dec 2005 2:21] Armin Schöffmann
OK, still 1 handle got lost in my code:
"vio->event_conn_closed" is asking for more care...:

this is the corrected patch:

r= UnmapViewOfFile(vio->handle_map)     &&
    CloseHandle(vio->event_server_wrote)  &&
    CloseHandle(vio->event_server_read)   &&
    CloseHandle(vio->event_client_wrote)  &&
    CloseHandle(vio->event_client_read)    &&
    CloseHandle(vio->handle_file_map)     &&
    CloseHandle(vio->event_conn_closed);
[19 Dec 2005 21:42] MySQL Verification Team
Thank you for the bug report.
I was unable to repeat the behavior for you reported, instead I
got 2 memory leaks according showed below with the Purify's
Report:

[I] Starting Purify'd bug15846.exe at 19/12/2005 19:35:18
        Instrumented executable: C:\Arquivos de programas\Rational\PurifyPlus\cache\bug15846$Purify_C_temp.exe
        Working directory:       C:\temp
        Command line arguments:  <none>
        Process ID:              0x60c
        Thread ID: 0xf00
[I] Starting main
[I] Summary of all memory leaks... {824 bytes, 3 blocks}
[I] MPK: Potential memory leak of 28 bytes from 1 block allocated in WLDAP32.dll
        Distribution of potentially leaked blocks
                28 bytes from 1 block of 28 bytes (0x0015c058) 
        Allocation location
             [KERNEL32.dll ip=0x6c8033c8]
             [WLDAP32.dll ip=0x76f41382]
             [WLDAP32.dll ip=0x76f41302]
             [WLDAP32.dll ip=0x76f415f7]
             [WLDAP32.dll ip=0x76f414ea]
             [WLDAP32.dll ip=0x76f41178]
             [ntdll.dll ip=0x7c9011a7]
             [ntdll.dll ip=0x7c91cbab]
             [ntdll.dll ip=0x7c916178]
             [ntdll.dll ip=0x7c9162da]
[I] MPK: Potential memory leak of 28 bytes from 1 block allocated in WLDAP32.dll
        Distribution of potentially leaked blocks
                28 bytes from 1 block of 28 bytes (0x0015ceb0) 
        Allocation location
             [KERNEL32.dll ip=0x6c8033c8]
             [WLDAP32.dll ip=0x76f41382]
             [WLDAP32.dll ip=0x76f41302]
             [WLDAP32.dll ip=0x76f411ce]
             [WLDAP32.dll ip=0x76f41178]
             [ntdll.dll ip=0x7c9011a7]
             [ntdll.dll ip=0x7c918f65]
             [ntdll.dll ip=0x7c918dde]
             [ntdll.dll ip=0x7c90eac7]
[I] MPK: Potential memory leak of 768 bytes from 1 block allocated in _init_ctype [LIBMYSQL.dll]
        Distribution of potentially leaked blocks
               768 bytes from 1 block of 768 bytes (0x01d159a0) 
        Allocation location
            malloc_dbg     [dbgheap.c:175]
            _init_ctype    [initctyp.c:107]
            setlocale_set_cat [setlocal.c:829]
            setlocale_lk   [setlocal.c:611]
            setlocale      [setlocal.c:550]
            my_win_init    [my_init.c:260]
            my_init        [my_init.c:102]
            libmysql_init  [dll.c:35]
            LibMain        [dll.c:62]
            DllMain        [dll.c:94]
[I] Summary of new memory leaks... {260 bytes, 3 blocks}
[I] MPK: Potential memory leak of 28 bytes from 1 block allocated in WLDAP32.dll
        Distribution of potentially leaked blocks
                28 bytes from 1 block of 28 bytes (0x0015cf20) 
        Allocation location
             [KERNEL32.dll ip=0x6c8033c8]
             [WLDAP32.dll ip=0x76f41382]
             [WLDAP32.dll ip=0x76f41302]
             [WLDAP32.dll ip=0x76f411ce]
             [WLDAP32.dll ip=0x76f41178]
             [ntdll.dll ip=0x7c9011a7]
             [ntdll.dll ip=0x7c918f65]
             [ntdll.dll ip=0x7c918dde]
             [ntdll.dll ip=0x7c90eac7]
[W] MLK: Memory leak of 140 bytes from 1 block allocated in CRT_INIT [LIBMYSQL.dll]
        Distribution of leaked blocks
               140 bytes from 1 block of 140 bytes (0x01d1fa60) 
        Allocation location
            calloc_dbg     [dbgheap.c:521]
            CRT_INIT       [dllcrt0.c:215]
            DllMainCRTStartup [dllcrt0.c:291]
             [ntdll.dll ip=0x7c918f65]
             [ntdll.dll ip=0x7c918dde]
             [ntdll.dll ip=0x7c90eac7]
[W] MLK: Memory leak of 92 bytes from 1 block allocated in my_thread_init [LIBMYSQL.dll]
        Distribution of leaked blocks
                92 bytes from 1 block of 92 bytes (0x01d1fb38) 
        Allocation location
            calloc         [dbgheap.c:480]
            my_thread_init [my_thr_init.c:170]
            LibMain        [dll.c:68]
            DllMain        [dll.c:94]
            DllMainCRTStartup [dllcrt0.c:297]
             [ntdll.dll ip=0x7c918f65]
             [ntdll.dll ip=0x7c918dde]
             [ntdll.dll ip=0x7c90eac7]
[20 Dec 2005 0:01] Armin Schöffmann
sample app (dyn. linked to libmysql.dll)

Attachment: MySQLAPITest.exe (application/x-msdos-program, text), 7.00 KiB.

[20 Dec 2005 0:03] Armin Schöffmann
testrun with unpatched lib

Attachment: output1.txt (text/plain), 2.03 KiB.

[20 Dec 2005 0:04] Armin Schöffmann
testrun with patched lib

Attachment: output2.txt (text/plain), 2.03 KiB.

[20 Dec 2005 0:04] Armin Schöffmann
testapp source

Attachment: MySQLAPITest.cpp (text/plain), 1.72 KiB.

[20 Dec 2005 0:17] Armin Schöffmann
purify is a nasty tool ;-)
find attached a console-app reproducing the handle-leak on my machine.
alternatively search through the complete mysql-api source and find the corresponding code that closes the handles opened in client.c "create_shared_memory(...)": there's none...

regards,armin.
[27 Feb 2006 14:41] Armin Schöffmann
Hello all,
is there any chance to see this issue fixed in 5.0.19?
The bug makes the (otherwise) appreciated shared-mem-feature useless.

There's a 10000 handle/process-limit on nt, which will latest be reached after 1666 consecutive mysql-connections. (In our case after 3 days).
[17 Mar 2006 8:12] 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/3908
[17 Mar 2006 8:29] 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/3910
[17 Mar 2006 10:41] Armin Schöffmann
Chad, your patch still leaves one handle open:
(vio->event_conn_closed)
[17 Mar 2006 17:47] 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/3936
[17 Mar 2006 17:52] Chad MILLER
Thank you, Armin.
[17 Mar 2006 23:30] Paul DuBois
Need the version into which this fix was pushed. Thanks.
[22 Mar 2006 19:04] Chad MILLER
It will be in 4.1.20, 5.0.20, and 5.1.8.
[11 Apr 2006 3:27] Paul DuBois
Noted in 4.1.19 (there is no 4.1.20 yet), 5.0.20, 5.1.8 changelogs.

The <literal>mysql_close()</literal> C API function leaked
handles for share-memory connections on Windows. (Bug #15846)