Bug #1069 libmysqlclient: unitialized values and some value aren't freed
Submitted: 18 Aug 2003 2:31 Modified: 16 Feb 2005 22:32
Reporter: Christian Hammers (Silver Quality Contributor) (OCA) Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server Severity:S3 (Non-critical)
Version:4.0.13 OS:Linux (GNU/Linux)
Assigned to: Guilhem Bichot CPU Architecture:Any

[18 Aug 2003 2:31] Christian Hammers
Description:
The following bug was reported to the Debian Bug Tracking System as #205587
(http://bugs.debian.org/205587). Please contact Jan Nejman <Jan.Nejman@cesnet.cz>
for further questions.

-christian-

--------------------------------------
Package: libmysqlclient-dev
Version: 4.0.13-3

For detecting memleak I'm using tool Valgrind ...
Problem is in package libmysqlclient probably
valgrind tool say:
1. Conditional jump or move depends on uninitialised value

2. LEAK SUMMARY:
==1798==    definitely lost: 30 bytes in 2 blocks.
==1798==    possibly lost:   0 bytes in 0 blocks.
==1798==    still reachable: 0 bytes in 0 blocks.

Conditional jump must be in function mysql_init ...
memleak is maybe related to charset ... but I'm not sure.

For problem demonstrating I create short code:
#include "malloc.h"
#include "stdlib.h"
#include "mysql/mysql.h"
#include "mysql/mysqld_error.h"

int main() {
  MYSQL *a;
  a=mysql_init(NULL);
  mysql_close(a);
  return 0;
}

This is valgrind's report:
netflow:/netflow/devel/nfc# valgrind -v --leak-check=yes
--show-reachable=yes ./a.out
==1798== Memcheck, a.k.a. Valgrind, a memory error detector for x86-linux.
==1798== Copyright (C) 2002, and GNU GPL'd, by Julian Seward.
==1798== Using valgrind-1.9.6, a program instrumentation system for
x86-linux.
==1798== Copyright (C) 2000-2002, and GNU GPL'd, by Julian Seward.
==1798== Startup, with flags:
==1798==    --suppressions=/usr/local/lib/valgrind/default.supp
==1798==    -v
==1798==    --leak-check=yes
==1798==    --show-reachable=yes
==1798== Reading suppressions file: /usr/local/lib/valgrind/default.supp
==1798== Estimated CPU clock rate is 870 MHz
==1798==
==1798== Reading syms from /netflow/devel/nfc/a.out
==1798==    object doesn't have any debug info
==1798== Reading syms from /lib/ld-2.3.2.so
==1798==    object doesn't have any debug info
==1798== Reading syms from /usr/local/lib/valgrind/vgskin_memcheck.so
==1798== Reading syms from /usr/local/lib/valgrind/valgrind.so
==1798== Reading syms from /usr/lib/libmysqlclient.so.12.0.0
==1798==    object doesn't have a symbol table
==1798==    object doesn't have any debug info
==1798== Reading syms from /lib/libc-2.3.2.so
==1798==    object doesn't have a symbol table
==1798==    object doesn't have any debug info
==1798== Reading syms from /usr/lib/libz.so.1.1.4
==1798==    object doesn't have a symbol table
==1798==    object doesn't have any debug info
==1798== Reading syms from /lib/libcrypt-2.3.2.so
==1798==    object doesn't have a symbol table
==1798==    object doesn't have any debug info
==1798== Reading syms from /lib/libnsl-2.3.2.so
==1798==    object doesn't have a symbol table
==1798==    object doesn't have any debug info
==1798== Reading syms from /lib/libm-2.3.2.so
==1798==    object doesn't have a symbol table
==1798==    object doesn't have any debug info
==1798== Reading syms from /usr/lib/i686/cmov/libssl.so.0.9.7
==1798==    object doesn't have a symbol table
==1798==    object doesn't have any debug info
==1798== Reading syms from /usr/lib/i686/cmov/libcrypto.so.0.9.7
==1798==    object doesn't have a symbol table
==1798==    object doesn't have any debug info
==1798== Reading syms from /lib/libdl-2.3.2.so
==1798== Reading syms from /usr/lib/i686/cmov/libcrypto.so.0.9.7
==1798==    object doesn't have a symbol table
==1798==    object doesn't have any debug info
==1798== Reading syms from /lib/libdl-2.3.2.so
==1798==    object doesn't have a symbol table
==1798==    object doesn't have any debug info
==1798== Reading syms from /lib/libnss_db-2.2.so
==1798==    object doesn't have a symbol table
==1798==    object doesn't have any debug info
==1798== Reading syms from /lib/libnss_files-2.3.2.so
==1798==    object doesn't have a symbol table
==1798==    object doesn't have any debug info
==1798== Reading syms from /usr/lib/libdb3.so.3.0.2
==1798==    object doesn't have a symbol table
==1798==    object doesn't have any debug info
==1798== Conditional jump or move depends on uninitialised value(s)
==1798==    at 0x40007EB8: _dl_relocate_object_internal (in
/lib/ld-2.3.2.so)
==1798==    by 0x40332D44: (within /lib/libc-2.3.2.so)
==1798==    by 0x4000A19E: _dl_catch_error_internal (in /lib/ld-2.3.2.so)
==1798==    by 0x40332F89: _dl_open (in /lib/libc-2.3.2.so)
==1798==
==1798== Conditional jump or move depends on uninitialised value(s)
==1798==    at 0x40007EFD: _dl_relocate_object_internal (in
/lib/ld-2.3.2.so)
==1798==    by 0x40332D44: (within /lib/libc-2.3.2.so)
==1798==    by 0x4000A19E: _dl_catch_error_internal (in /lib/ld-2.3.2.so)
==1798==    by 0x40332F89: _dl_open (in /lib/libc-2.3.2.so)
==1798== discard syms in /lib/libnss_db-2.2.so due to munmap()
==1798== discard syms in /usr/lib/libdb3.so.3.0.2 due to munmap()
==1798== discard syms in /lib/libnss_files-2.3.2.so due to munmap()
==1798==
==1798== ERROR SUMMARY: 6 errors from 2 contexts (suppressed: 0 from 0)
==1798==
==1798== 3 errors in context 1 of 2:
==1798== Conditional jump or move depends on uninitialised value(s)
==1798==    at 0x40007EFD: _dl_relocate_object_internal (in
/lib/ld-2.3.2.so)
==1798==    by 0x40332D44: (within /lib/libc-2.3.2.so)
==1798==    by 0x4000A19E: _dl_catch_error_internal (in /lib/ld-2.3.2.so)
==1798==    by 0x40332F89: _dl_open (in /lib/libc-2.3.2.so)
==1798==
==1798== 3 errors in context 2 of 2:
==1798== Conditional jump or move depends on uninitialised value(s)
==1798==    at 0x40007EB8: _dl_relocate_object_internal (in
/lib/ld-2.3.2.so)
==1798==    by 0x40332D44: (within /lib/libc-2.3.2.so)
==1798==    by 0x4000A19E: _dl_catch_error_internal (in /lib/ld-2.3.2.so)
==1798==    by 0x40332F89: _dl_open (in /lib/libc-2.3.2.so)
==1798== IN SUMMARY: 6 errors from 2 contexts (suppressed: 0 from 0)
==1798==
==1798== malloc/free: in use at exit: 30 bytes in 2 blocks.
==1798== malloc/free: 61 allocs, 59 frees, 6476 bytes allocated.
==1798==
==1798== searching for pointers to 2 not-freed blocks.
==1798== checked 5160116 bytes.
==1798==
==1798== 4 bytes in 1 blocks are definitely lost in loss record 1 of 2
==1798==    at 0x4015E394: malloc (vg_clientfuncs.c:103)
==1798==    by 0x400045E8: _dl_map_object_from_fd (in /lib/ld-2.3.2.so)
==1798==    by 0x400054D6: _dl_map_object_internal (in /lib/ld-2.3.2.so)
==1798==    by 0x40008DA0: openaux (in /lib/ld-2.3.2.so)
==1798==
==1798== 26 bytes in 1 blocks are definitely lost in loss record 2 of 2
==1798==    at 0x4015E394: malloc (vg_clientfuncs.c:103)
==1798==    by 0x4149F5AE: ???
==1798==    by 0x4149F486: ???
==1798==    by 0x41474D8E: ???
==1798==
==1798== LEAK SUMMARY:
==1798==    definitely lost: 30 bytes in 2 blocks.
==1798==    possibly lost:   0 bytes in 0 blocks.
==1798==    still reachable: 0 bytes in 0 blocks.
==1798==         suppressed: 0 bytes in 0 blocks.
==1798==
--1798--     TT/TC: 0 tc sectors discarded.
--1798--            1932 chainings, 0 unchainings.
--1798-- translate: new     3010 (47741 -> 658702; ratio 137:10)
--1798--            discard 513 (9256 -> 117832; ratio 127:10).
--1798--  dispatch: 100000 jumps (bb entries), of which 18623 (18%) were
unchained.
--1798--            4/3326 major/minor sched events.  3128 tt_fast misses.
--1798-- reg-alloc: 470 t-req-spill, 123737+2526 orig+spill uis, 15287
total-reg-r.
--1798--    sanity: 5 cheap, 1 expensive checks.
--1798--    ccalls: 14059 C calls, 54% saves+restores avoided (45264 bytes)
--1798--            17983 args, avg 0.89 setup instrs each (3842 bytes)
--1798--            0% clear the stack (42177 bytes)
--1798--            5143 retvals, 33% of reg-reg movs avoided (3308 bytes)

I'm using Linux netflow 2.4.21 #2 SMP Mon Jun 23 14:05:06 CEST 2003 i686
GNU/Linux and libc-2.3.2.so ...

                Thank you, Jan Nejman

How to repeat:
...
[21 Aug 2003 12:18] Michael Widenius
Not enough information was provided for us to be able
to handle this bug. Please re-read the instructions at
http://bugs.mysql.com/how-to-report.php

If you can provide more information, feel free to add it
to this bug and change the status back to 'Open'.

Thank you for your interest in MySQL.

I tested your program with the following setup:
SuSE Linux 8.2 (Sorry but I don't have access to a box with Debian)
Kernel: 2.4.20-64GB-SMP
valgrind 20030725
glibc 2.3.2-6
gcc 3.2.2
MySQL 4.0.15 (to be relesed soon)
MySQL was compiled with the script: BUILD/compile-pentium-valgrind-max

I compiled and tested your program as follows:

gcc -o skr -I'/usr/local/mysql/include/mysql' skr.c -L'/usr/local/mysql/lib/mysql' -lmysqlclient -lz -lcrypt -lnsl -lm -L/usr/lib -lssl -lcrypto
valgrind --leak-check=yes --show-reachable=yes skr

When testing with a MySQL library version compiled for the debugging I got:

==24047== 556 bytes in 1 blocks are still reachable in loss record 1 of 1
==24047==    at 0x40029845: malloc (vg_replace_malloc.c:153)
==24047==    by 0x4025A26B: DbugMalloc (dbug.c:1614)
==24047==    by 0x40259B69: PushState (dbug.c:1123)
==24047==    by 0x402590F8: _db_push_ (dbug.c:513)

This is a block that is allocated once by the DEBUG package and future calls to MySQL will reuse it.

From your bug report it looks like this is not the block you found (based on the size of the block and that your block is not reachable).

My guess is that the memory allocation comes from some library MySQL uses and is not directly MySQL related.

You can test if this is a fatal error by changing your program to call mysql_init()/mysql_close() several times and see if you this way get additional memory leaks.

To find the source for the error, please start the program under gbd and put a breakpoint in malloc() to see from where the blocks are allocated.
If we could know where the block was allocated, we would know a lot more..

Regrads,
Monty
[8 Feb 2005 19:45] Sergei Golubchik
No feedback was provided. The bug is being suspended because
we assume that you are no longer experiencing the problem.
If this is not the case and you are able to provide the
information that was requested earlier, please do so and
change the status of the bug back to "Open". Thank you.
[8 Feb 2005 22:29] Christian Hammers
Hello

This bug report is quite old but I can still reproduce the original valgrind output with both libmysqlclient12 and libmysqlclient14. Sadly I cannot find a way to resolve theses missing symbol names so I archived the outputs, binaries and needed libraries and made them available at my homepage as they were too big for the bug tracking system:
 http://www.lathspell.de/linux/debian/mysql/mysql-memleak-debug.tar.bz2

I even tried valgrinding it with "LD_LIBRARY_PATH=/usr/lib/debug ..." where the libc6 with debugging symbols resides but the symbols still don't resolve.

Setting a breakpoint in gdb with "b malloc" gave message that malloc was resolved after  I typed run but still it did not break there.

I'm willing to do more tests but please give me detailed instructions :)

bye,

-christian-
[15 Feb 2005 20:22] Sergei Golubchik
for "charset related" leak it's bug#6149 - that is fixed in 4.1.10
[16 Feb 2005 22:32] Guilhem Bichot
Hello Christian.
Yes, with the user's test program, Valgrind is expected to complain about non-freed memory (charset-related, though I don't see it in your output). This is memory which is allocated the very first time the program calls mysql_init(). To explicitely free it when the program exits, thus making Valgrind happy, one should include a mysql_server_end() (aliased as mysql_library_end() starting from 4.1.10 and 5.0.3) call before exiting (when the program is done with using libmysqlclient calls). The problem is that our doc wasn't clear enough about mysql_server_end(), that was BUG#6149, doc is now fixed:
http://dev.mysql.com/doc/mysql/en/c-api-function-overview.html
Now the issues reported by the Debian user:

1)
==1798== Conditional jump or move depends on uninitialised value(s)
==1798==    at 0x40007EFD: _dl_relocate_object_internal (in 
/lib/ld-2.3.2.so)
==1798==    by 0x40332D44: (within /lib/libc-2.3.2.so)
==1798==    by 0x4000A19E: _dl_catch_error_internal (in /lib/ld-2.3.2.so)
==1798==    by 0x40332F89: _dl_open (in /lib/libc-2.3.2.so)

I always got that one myself, it's not in MySQL itself, I think it went away when I upgraded my distro. So, nothing to do about it.

2)
==1798== 4 bytes in 1 blocks are definitely lost in loss record 1 of 2
==1798==    at 0x4015E394: malloc (vg_clientfuncs.c:103)
==1798==    by 0x400045E8: _dl_map_object_from_fd (in /lib/ld-2.3.2.so)
==1798==    by 0x400054D6: _dl_map_object_internal (in /lib/ld-2.3.2.so)
==1798==    by 0x40008DA0: openaux (in /lib/ld-2.3.2.so)

Again, the dl* syscalls() look guilty.

3)
==1798== 26 bytes in 1 blocks are definitely lost in loss record 2 of 2
==1798==    at 0x4015E394: malloc (vg_clientfuncs.c:103)
==1798==    by 0x4149F5AE: ???
==1798==    by 0x4149F486: ???
==1798==    by 0x41474D8E: ???

No strack trace (??), so probably not MySQL.

Honestly, I think those errors should be labelled "the mysteries of some versions of system libraries when run under some versions of Valgrind". I experienced some of these, I even experienced one which went away by removing the -O1 optimisation.