[debian-mysql] Bug#615613: Memory leak when opening a database using libmysqlclient-dev in C

Král Gergely kralg at robolution.eu
Sun Feb 27 19:07:32 UTC 2011


Package: libmysqlclient-dev
Version: 5.1.49-3
Severity: important

Hi,

I am pretty much uncertain if it is really a bug in the package or a bug in me, sorry in case I am on the wrong track.

Here is how I compile the following codes:
$ cc -o memleak -L/usr/lib/mysql -lmysqlclient memleak.c -Wall -Werror

And how I check for memory leak:
$ valgrind --leak-check=full --show-reachable=yes ./memleak

First I simply open a database:
-----------------
#include <fcntl.h>
#include <stddef.h>
#include <mysql/mysql.h>
#include <unistd.h>

int main( void ) {
  MYSQL *mysqlKapcsolat;

  mysqlKapcsolat = mysql_init( NULL ); 
  mysql_real_connect( mysqlKapcsolat, "localhost", "vezerles", "s3mUswes", "vezerles", 0, NULL, 0 );

  return 0;
}
-------------------
valgrind output, only the summary:
-------------------
==10945== LEAK SUMMARY:
==10945==    definitely lost: 964 bytes in 1 blocks
==10945==    indirectly lost: 24,901 bytes in 8 blocks
==10945==      possibly lost: 53,144 bytes in 13 blocks
==10945==    still reachable: 8,192 bytes in 3 blocks
==10945==         suppressed: 0 bytes in 0 blocks
-------------------
At this point I believe this is not OK, even though I am not closing the connection. Now I will:
-------------------
#include <fcntl.h>
#include <stddef.h>
#include <mysql/mysql.h>
#include <unistd.h>

int main( void ) {
  MYSQL *mysqlKapcsolat;

  mysqlKapcsolat = mysql_init( NULL );
  mysql_real_connect( mysqlKapcsolat, "localhost", "vezerles", "s3mUswes", "vezerles", 0, NULL, 0 );
  mysql_close( mysqlKapcsolat );

  return 0;
}
---------------------
valgrind ouput:
---------------------
==11052== LEAK SUMMARY:
==11052==    definitely lost: 0 bytes in 0 blocks
==11052==    indirectly lost: 0 bytes in 0 blocks
==11052==      possibly lost: 53,144 bytes in 13 blocks
==11052==    still reachable: 8,192 bytes in 3 blocks
==11052==         suppressed: 0 bytes in 0 blocks
--------------------
This looks somewhat better, however still not OK as far as I know. Now I am doing a couple of queries in a row:
--------------------
#include <fcntl.h>
#include <stddef.h>
#include <mysql/mysql.h>
#include <unistd.h>

int main( void ) {
  MYSQL *mysqlKapcsolat;
  MYSQL_RES *mysqlEredmeny;
  MYSQL_ROW mysqlSor;
  short int index = 0;

  mysqlKapcsolat = mysql_init( NULL );
  mysql_real_connect( mysqlKapcsolat, "localhost", "vezerles", "s3mUswes", "vezerles", 0, NULL, 0 );
  while( 20 > index ) {
    mysql_query( mysqlKapcsolat, "SELECT kimenet_ertek FROM futes WHERE hely = 'iroda'" );
    mysqlEredmeny = mysql_store_result( mysqlKapcsolat );
    mysqlSor = mysql_fetch_row( mysqlEredmeny );
    index++;
    sleep( 5 );
  }

  mysql_close( mysqlKapcsolat );
  return 0;
}
------------------
valgrind output:
------------------
==11200== LEAK SUMMARY:
==11200==    definitely lost: 1,840 bytes in 20 blocks
==11200==    indirectly lost: 286,860 bytes in 55 blocks
==11200==      possibly lost: 93,964 bytes in 18 blocks
==11200==    still reachable: 8,192 bytes in 3 blocks
==11200==         suppressed: 0 bytes in 0 blocks
------------------
This is bad I guess, lost memory proportionally increases with the number of iterations. According to the documentation I only need to use mysql_free_result() if I am worried about the possibly huge amount of information read in. Lets use it now:
------------------
#include <fcntl.h>
#include <stddef.h>
#include <mysql/mysql.h>
#include <unistd.h>

int main( void ) {
  MYSQL *mysqlKapcsolat;
  MYSQL_RES *mysqlEredmeny;
  MYSQL_ROW mysqlSor;
  short int index = 0;

  mysqlKapcsolat = mysql_init( NULL );
  mysql_real_connect( mysqlKapcsolat, "localhost", "vezerles", "s3mUswes", "vezerles", 0, NULL, 0 );
  while( 30 > index ) {
    mysql_query( mysqlKapcsolat, "SELECT kimenet_ertek FROM futes WHERE hely = 'iroda'" );
    mysqlEredmeny = mysql_store_result( mysqlKapcsolat );
    mysqlSor = mysql_fetch_row( mysqlEredmeny );
    mysql_free_result( mysqlEredmeny );
    index++;
    sleep( 5 );
  }

  mysql_close( mysqlKapcsolat );
  return 0;
}
-------------------
valgrind output:
-------------------
==11318== LEAK SUMMARY:
==11318==    definitely lost: 0 bytes in 0 blocks
==11318==    indirectly lost: 0 bytes in 0 blocks
==11318==      possibly lost: 53,144 bytes in 13 blocks
==11318==    still reachable: 8,192 bytes in 3 blocks
==11318==         suppressed: 0 bytes in 0 blocks
------------------
This seems to have helped, but still makes me feel uncomfortable.

If everything above is normal then sorry for bothering. Let me know if I can provide any more information.

$ valgrind --version
valgrind-3.6.0.SVN-Debian

-- System Information:
Debian Release: squeeze/sid
  APT prefers testing
  APT policy: (500, 'testing')
Architecture: i386 (i686)

Kernel: Linux 2.6.32-5-686 (SMP w/2 CPU cores)
Locale: LANG=hu_HU.UTF-8, LC_CTYPE=hu_HU.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash

Versions of packages libmysqlclient-dev depends on:
ii  libc6                   2.11.2-11        Embedded GNU C Library: Shared lib
ii  libgcc1                 1:4.4.5-10       GCC support library
ii  libmysqlclient16        5.1.49-3         MySQL database client library
ii  libstdc++6              4.4.5-10         The GNU Standard C++ Library v3
ii  zlib1g-dev              1:1.2.3.4.dfsg-3 compression library - development

libmysqlclient-dev recommends no packages.

libmysqlclient-dev suggests no packages.

-- no debconf information





More information about the pkg-mysql-maint mailing list