Bug #76436 [Opn]: mysqli memory leak mysqli_fetch_object
| From: | luca dot looz92 at gmail dot com | Date: | Sat, 09 Jun 2018 20:36:24 +0000 |
| Subject: | Bug #76436 [Opn]: mysqli memory leak mysqli_fetch_object | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-215568@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=76436&edit=1
ID: 76436
User updated by: luca dot looz92 at gmail dot com
Reported by: luca dot looz92 at gmail dot com
Summary: mysqli memory leak mysqli_fetch_object
Status: Open
Type: Bug
Package: MySQLi related
Operating System: centos 7
PHP Version: 7.2.6
Block user comment: N
Private report: N
New Comment:
The leak doesn't happen on 7.3.0alpha1 just compiled from the source.
In addition to valgrind i'm also running the sample php script under php-fpm and sending
requests with "vegeta" for a couple of hours.
Previous Comments:
------------------------------------------------------------------------
[2018-06-09 19:51:37] luca dot looz92 at gmail dot com
After digging a bit i think that maybe the trace reported by valgrind is incorrect and reports some
other memory. The leak is definitively present but when it happens it's about 4 byte for an
entire request.
The leak isn't present on 7.1.x
------------------------------------------------------------------------
[2018-06-09 09:57:33] luca dot looz92 at gmail dot com
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 this bug report at https://bugs.php.net/bug.php?id=76436&edit=1