Bug #76436 [NEW]: mysqli memory leak mysqli_fetch_object
| From: | luca dot looz92 at gmail dot com | Date: | Sat, 09 Jun 2018 09:57:35 +0000 |
| Subject: | Bug #76436 [NEW]: mysqli memory leak mysqli_fetch_object | ||
| Groups: | php.bugs | ||
| Request: | Send a blank email to php-bugs+get-215557@lists.php.net to get a copy of this message | ||
From: luca dot looz92 at gmail dot com
Operating system: centos 7
PHP version: 7.2.6
Package: MySQLi related
Bug Type: Bug
Bug description:mysqli memory leak mysqli_fetch_object
Description:
------------
I was going crazy by investigating a memory issue on our server, php-fpm
pools after a couple of days exhausts 16gb of RAM.
By doing a lot of tests with trials and errors i was able to reproduce
the issue.
The memory leak happens when using functions like "mysqli_fetch_object"
and "mysqli_fetch_array". Doesn't happen with "mysqli_fetch_row".
I'm able to reproduce this by compiling php 7.2.6 from source with just
the mysqli module:
./configure --disable-all --with-mysqli
A very strange thing is that if I compile php in debug mode the leak
doesn't happen anymore...
./configure --disable-all --enable-debug --with-mysqli
If I put the code in a loop the leak doesn't become bigger so it seems
that is limited per script execution by leaking something like 4 bytes
for each execution.
To test this I used the Wordpress default database by reading the hello
world article.
I have attached the valgrind results with "export
ZEND_DONT_UNLOAD_MODULES=1".
Another thing to note is that if set "export USE_ZEND_ALLOC=0" with the
non-debug version the leak doesn't happen.
I've seen this issue on 7.2.2, 7.2.5 and 7.2.6.
Test script:
---------------
<?php
$dbh = mysqli_init();
mysqli_real_connect( $dbh, '127.0.0.1', 'root', 'mydbpass');
mysqli_select_db( $dbh, 'dbwpempty' );
$result = mysqli_query( $dbh, "SELECT * FROM wp_posts WHERE ID = 1
LIMIT 1" );
$num_rows = 0;
$last_result = array();
while ( $row = mysqli_fetch_object( $result ) ) {
$last_result[$num_rows] = $row;
$num_rows++;
}
$result->free();
$dbh->close();
?>
valgrind --leak-check=full php mysqlleak.php
Expected result:
----------------
==30485== HEAP SUMMARY:
==30485== in use at exit: 32 bytes in 1 blocks
==30485== total heap usage: 10,515 allocs, 10,514 frees, 1,983,262
bytes allocated
==30485==
==30485== LEAK SUMMARY:
==30485== definitely lost: 0 bytes in 0 blocks
==30485== indirectly lost: 0 bytes in 0 blocks
==30485== possibly lost: 0 bytes in 0 blocks
==30485== still reachable: 32 bytes in 1 blocks
==30485== suppressed: 0 bytes in 0 blocks
Actual result:
--------------
==30483== HEAP SUMMARY:
==30483== in use at exit: 936 bytes in 24 blocks
==30483== total heap usage: 9,275 allocs, 9,251 frees, 1,466,918 bytes
allocated
==30483==
==30483== 904 bytes in 23 blocks are definitely lost in loss record 2 of
2
==30483== at 0x4C29C23: malloc (vg_replace_malloc.c:299)
==30483== by 0x5B1198: __zend_malloc (zend_alloc.c:2829)
==30483== by 0x564684: zend_string_alloc (zend_string.h:134)
==30483== by 0x564684: zend_string_init (zend_string.h:170)
==30483== by 0x564684: php_mysqlnd_rset_field_read
(mysqlnd_wireprotocol.c:1378)
==30483== by 0x56DA81: mysqlnd_mysqlnd_res_meta_read_metadata_pub
(mysqlnd_result_meta.c:76)
==30483== by 0x56A2B6: mysqlnd_mysqlnd_res_read_result_metadata_pub
(mysqlnd_result.c:385)
==30483== by 0x56C8D0: mysqlnd_query_read_result_set_header
(mysqlnd_result.c:539)
==30483== by 0x55B152: mysqlnd_mysqlnd_conn_data_reap_query_pub
(mysqlnd_connection.c:917)
==30483== by 0x55D79E: mysqlnd_mysqlnd_conn_data_query_pub
(mysqlnd_connection.c:859)
==30483== by 0x4AA001: zif_mysqli_query (mysqli_nonapi.c:593)
==30483== by 0x671C93: ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER
(zend_vm_execute.h:617)
==30483== by 0x671C93: execute_ex (zend_vm_execute.h:59734)
==30483== by 0x67A690: zend_execute (zend_vm_execute.h:63760)
==30483== by 0x5D8FC7: zend_execute_scripts (zend.c:1496)
==30483==
==30483== LEAK SUMMARY:
==30483== definitely lost: 904 bytes in 23 blocks
==30483== indirectly lost: 0 bytes in 0 blocks
==30483== possibly lost: 0 bytes in 0 blocks
==30483== still reachable: 32 bytes in 1 blocks
==30483== suppressed: 0 bytes in 0 blocks
==30483== Reachable blocks (those to which a pointer was found) are not
shown.
--
Edit bug report at https://bugs.php.net/bug.php?id=76436&edit=1
--
Try a snapshot (PHP 5.4): https://bugs.php.net/fix.php?id=76436&r=trysnapshot54
Try a snapshot (PHP 5.5): https://bugs.php.net/fix.php?id=76436&r=trysnapshot55
Try a snapshot (trunk): https://bugs.php.net/fix.php?id=76436&r=trysnapshottrunk
Fixed in SVN: https://bugs.php.net/fix.php?id=76436&r=fixed
Fixed in release: https://bugs.php.net/fix.php?id=76436&r=alreadyfixed
Need backtrace: https://bugs.php.net/fix.php?id=76436&r=needtrace
Need Reproduce Script: https://bugs.php.net/fix.php?id=76436&r=needscript
Try newer version: https://bugs.php.net/fix.php?id=76436&r=oldversion
Not developer issue: https://bugs.php.net/fix.php?id=76436&r=support
Expected behavior: https://bugs.php.net/fix.php?id=76436&r=notwrong
Not enough info: https://bugs.php.net/fix.php?id=76436&r=notenoughinfo
Submitted twice: https://bugs.php.net/fix.php?id=76436&r=submittedtwice
register_globals: https://bugs.php.net/fix.php?id=76436&r=globals
PHP 4 support discontinued: https://bugs.php.net/fix.php?id=76436&r=php4
Daylight Savings: https://bugs.php.net/fix.php?id=76436&r=dst
IIS Stability: https://bugs.php.net/fix.php?id=76436&r=isapi
Install GNU Sed: https://bugs.php.net/fix.php?id=76436&r=gnused
Floating point limitations: https://bugs.php.net/fix.php?id=76436&r=float
No Zend Extensions: https://bugs.php.net/fix.php?id=76436&r=nozend
MySQL Configuration Error: https://bugs.php.net/fix.php?id=76436&r=mysqlcfg