php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #78698 Memory Leak in realpath_cache when using ZTS Embed SAPI
Submitted: 2019-10-19 20:14 UTC Modified: 2019-11-07 13:53 UTC
From: maroszek at gmx dot net Assigned:
Status: Closed Package: *General Issues
PHP Version: 7.3.10 OS: Ubuntu
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: maroszek at gmx dot net
New email:
PHP Version: OS:

 

 [2019-10-19 20:14 UTC] maroszek at gmx dot net
Description:
------------
Description:
------------
PHP 7.3.10 is current stable
PHP 7.3.10 is build as a static library

./configure '--disable-fpm' '--disable-cgi' '--disable-cli' '--enable-embed=static' '--enable-maintainer-zts' '--without-iconv'

g++ --version
> g++ (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0

I build a simple example to demonstrate the leak.

Sourcecode: https://gist.github.com/paresy/3cbd4c6a469511ac7479aa0e7c42fea7

Copy leak.cpp into your php7 folder.

Compile with: g++ leak.cpp -Imain -ITSRM -IZend -I. --std=c++11 -Llibs -lphp7 -lxml2 -lresolv

test.php:
<?

Start it using valgrind: USE_ZEND_ALLOC=0 valgrind --leak-check=full ./a.out


Expected result:
----------------
No leak.

Actual result:
--------------

==25026== 
==25026== HEAP SUMMARY:
==25026==     in use at exit: 62,694 bytes in 570 blocks
==25026==   total heap usage: 311,182 allocs, 310,612 frees, 2,130,600,706 bytes allocated
==25026== 
==25026== 1,200 bytes in 50 blocks are definitely lost in loss record 21 of 31
==25026==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==25026==    by 0x229A58: __zend_malloc (zend_alloc.c:2903)
==25026==    by 0x531B42: php_pcre2_general_context_create (pcre2_context.c:121)
==25026==    by 0x31E87C: php_pcre_init_pcre2 (php_pcre.c:170)
==25026==    by 0x31E941: zm_globals_ctor_pcre (php_pcre.c:266)
==25026==    by 0x1F01EB: allocate_new_resource (TSRM.c:317)
==25026==    by 0x1F07A0: ts_resource_ex (TSRM.c:375)
==25026==    by 0x1EDF5F: main::{lambda()#1}::operator()() const (in /home/symcon/php-leak/php-7.3.10/a.out)
==25026==    by 0x1EE9EA: void std::__invoke_impl<void, main::{lambda()#1}>(std::__invoke_other, main::{lambda()#1}&&) (in /home/symcon/php-leak/php-7.3.10/a.out)
==25026==    by 0x1EE805: std::__invoke_result<main::{lambda()#1}>::type std::__invoke<main::{lambda()#1}>(std::__invoke_result&&, (main::{lambda()#1}&&)...) (in /home/symcon/php-leak/php-7.3.10/a.out)
==25026==    by 0x1EEC55: decltype (__invoke((_S_declval<0ul>)())) std::thread::_Invoker<std::tuple<main::{lambda()#1}> >::_M_invoke<0ul>(std::_Index_tuple<0ul>) (in /home/symcon/php-leak/php-7.3.10/a.out)
==25026==    by 0x1EEC11: std::thread::_Invoker<std::tuple<main::{lambda()#1}> >::operator()() (in /home/symcon/php-leak/php-7.3.10/a.out)
==25026== 
==25026== 2,700 bytes in 50 blocks are definitely lost in loss record 24 of 31
==25026==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==25026==    by 0x285EF2: realpath_cache_add (zend_virtual_cwd.c:645)
==25026==    by 0x285EF2: tsrm_realpath_r (zend_virtual_cwd.c:1213)
==25026==    by 0x285D62: tsrm_realpath_r (zend_virtual_cwd.c:1172)
==25026==    by 0x285D62: tsrm_realpath_r (zend_virtual_cwd.c:1172)
==25026==    by 0x285D62: tsrm_realpath_r (zend_virtual_cwd.c:1172)
==25026==    by 0x285D62: tsrm_realpath_r (zend_virtual_cwd.c:1172)
==25026==    by 0x286EE1: virtual_file_ex (zend_virtual_cwd.c:1353)
==25026==    by 0x288536: tsrm_realpath (zend_virtual_cwd.c:1943)
==25026==    by 0x1F8A8B: php_resolve_path (fopen_wrappers.c:568)
==25026==    by 0x583CCC: phar_find_in_include_path (util.c:282)
==25026==    by 0x20EEA2: _php_stream_open_wrapper_ex (streams.c:2006)
==25026==    by 0x1F2248: php_stream_open_for_zend_ex (main.c:1580)
==25026== 
==25026== 3,050 bytes in 50 blocks are definitely lost in loss record 25 of 31
==25026==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==25026==    by 0x285EF2: realpath_cache_add (zend_virtual_cwd.c:645)
==25026==    by 0x285EF2: tsrm_realpath_r (zend_virtual_cwd.c:1213)
==25026==    by 0x285D62: tsrm_realpath_r (zend_virtual_cwd.c:1172)
==25026==    by 0x285D62: tsrm_realpath_r (zend_virtual_cwd.c:1172)
==25026==    by 0x285D62: tsrm_realpath_r (zend_virtual_cwd.c:1172)
==25026==    by 0x286EE1: virtual_file_ex (zend_virtual_cwd.c:1353)
==25026==    by 0x288536: tsrm_realpath (zend_virtual_cwd.c:1943)
==25026==    by 0x1F8A8B: php_resolve_path (fopen_wrappers.c:568)
==25026==    by 0x583CCC: phar_find_in_include_path (util.c:282)
==25026==    by 0x20EEA2: _php_stream_open_wrapper_ex (streams.c:2006)
==25026==    by 0x1F2248: php_stream_open_for_zend_ex (main.c:1580)
==25026==    by 0x27437B: zend_stream_fixup (zend_stream.c:174)
==25026== 
==25026== 3,500 bytes in 50 blocks are definitely lost in loss record 26 of 31
==25026==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==25026==    by 0x285EF2: realpath_cache_add (zend_virtual_cwd.c:645)
==25026==    by 0x285EF2: tsrm_realpath_r (zend_virtual_cwd.c:1213)
==25026==    by 0x285D62: tsrm_realpath_r (zend_virtual_cwd.c:1172)
==25026==    by 0x285D62: tsrm_realpath_r (zend_virtual_cwd.c:1172)
==25026==    by 0x286EE1: virtual_file_ex (zend_virtual_cwd.c:1353)
==25026==    by 0x288536: tsrm_realpath (zend_virtual_cwd.c:1943)
==25026==    by 0x1F8A8B: php_resolve_path (fopen_wrappers.c:568)
==25026==    by 0x583CCC: phar_find_in_include_path (util.c:282)
==25026==    by 0x20EEA2: _php_stream_open_wrapper_ex (streams.c:2006)
==25026==    by 0x1F2248: php_stream_open_for_zend_ex (main.c:1580)
==25026==    by 0x27437B: zend_stream_fixup (zend_stream.c:174)
==25026==    by 0x218198: open_file_for_scanning (zend_language_scanner.l:515)
==25026== 
==25026== 3,600 bytes in 50 blocks are definitely lost in loss record 27 of 31
==25026==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==25026==    by 0x229A58: __zend_malloc (zend_alloc.c:2903)
==25026==    by 0x531ABE: _pcre2_memctl_malloc_8 (pcre2_context.c:89)
==25026==    by 0x531B70: php_pcre2_compile_context_create (pcre2_context.c:150)
==25026==    by 0x31E84D: php_pcre_init_pcre2 (php_pcre.c:178)
==25026==    by 0x31E941: zm_globals_ctor_pcre (php_pcre.c:266)
==25026==    by 0x1F01EB: allocate_new_resource (TSRM.c:317)
==25026==    by 0x1F07A0: ts_resource_ex (TSRM.c:375)
==25026==    by 0x1EDF5F: main::{lambda()#1}::operator()() const (in /home/symcon/php-leak/php-7.3.10/a.out)
==25026==    by 0x1EE9EA: void std::__invoke_impl<void, main::{lambda()#1}>(std::__invoke_other, main::{lambda()#1}&&) (in /home/symcon/php-leak/php-7.3.10/a.out)
==25026==    by 0x1EE805: std::__invoke_result<main::{lambda()#1}>::type std::__invoke<main::{lambda()#1}>(std::__invoke_result&&, (main::{lambda()#1}&&)...) (in /home/symcon/php-leak/php-7.3.10/a.out)
==25026==    by 0x1EEC55: decltype (__invoke((_S_declval<0ul>)())) std::thread::_Invoker<std::tuple<main::{lambda()#1}> >::_M_invoke<0ul>(std::_Index_tuple<0ul>) (in /home/symcon/php-leak/php-7.3.10/a.out)
==25026== 
==25026== 4,050 bytes in 50 blocks are definitely lost in loss record 28 of 31
==25026==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==25026==    by 0x285EF2: realpath_cache_add (zend_virtual_cwd.c:645)
==25026==    by 0x285EF2: tsrm_realpath_r (zend_virtual_cwd.c:1213)
==25026==    by 0x285D62: tsrm_realpath_r (zend_virtual_cwd.c:1172)
==25026==    by 0x286EE1: virtual_file_ex (zend_virtual_cwd.c:1353)
==25026==    by 0x288536: tsrm_realpath (zend_virtual_cwd.c:1943)
==25026==    by 0x1F8A8B: php_resolve_path (fopen_wrappers.c:568)
==25026==    by 0x583CCC: phar_find_in_include_path (util.c:282)
==25026==    by 0x20EEA2: _php_stream_open_wrapper_ex (streams.c:2006)
==25026==    by 0x1F2248: php_stream_open_for_zend_ex (main.c:1580)
==25026==    by 0x27437B: zend_stream_fixup (zend_stream.c:174)
==25026==    by 0x218198: open_file_for_scanning (zend_language_scanner.l:515)
==25026==    by 0x218586: compile_file (zend_language_scanner.l:629)
==25026== 
==25026== 6,700 bytes in 50 blocks are definitely lost in loss record 29 of 31
==25026==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==25026==    by 0x285EF2: realpath_cache_add (zend_virtual_cwd.c:645)
==25026==    by 0x285EF2: tsrm_realpath_r (zend_virtual_cwd.c:1213)
==25026==    by 0x286EE1: virtual_file_ex (zend_virtual_cwd.c:1353)
==25026==    by 0x288536: tsrm_realpath (zend_virtual_cwd.c:1943)
==25026==    by 0x1F8A8B: php_resolve_path (fopen_wrappers.c:568)
==25026==    by 0x583CCC: phar_find_in_include_path (util.c:282)
==25026==    by 0x20EEA2: _php_stream_open_wrapper_ex (streams.c:2006)
==25026==    by 0x1F2248: php_stream_open_for_zend_ex (main.c:1580)
==25026==    by 0x27437B: zend_stream_fixup (zend_stream.c:174)
==25026==    by 0x218198: open_file_for_scanning (zend_language_scanner.l:515)
==25026==    by 0x218586: compile_file (zend_language_scanner.l:629)
==25026==    by 0x437E10: phar_compile_file (phar.c:3347)
==25026== 
==25026== 7,200 (4,000 direct, 3,200 indirect) bytes in 50 blocks are definitely lost in loss record 30 of 31
==25026==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==25026==    by 0x229A58: __zend_malloc (zend_alloc.c:2903)
==25026==    by 0x531ABE: _pcre2_memctl_malloc_8 (pcre2_context.c:89)
==25026==    by 0x531C00: php_pcre2_match_context_create (pcre2_context.c:182)
==25026==    by 0x31E8A5: php_pcre_init_pcre2 (php_pcre.c:192)
==25026==    by 0x31E941: zm_globals_ctor_pcre (php_pcre.c:266)
==25026==    by 0x1F01EB: allocate_new_resource (TSRM.c:317)
==25026==    by 0x1F07A0: ts_resource_ex (TSRM.c:375)
==25026==    by 0x1EDF5F: main::{lambda()#1}::operator()() const (in /home/symcon/php-leak/php-7.3.10/a.out)
==25026==    by 0x1EE9EA: void std::__invoke_impl<void, main::{lambda()#1}>(std::__invoke_other, main::{lambda()#1}&&) (in /home/symcon/php-leak/php-7.3.10/a.out)
==25026==    by 0x1EE805: std::__invoke_result<main::{lambda()#1}>::type std::__invoke<main::{lambda()#1}>(std::__invoke_result&&, (main::{lambda()#1}&&)...) (in /home/symcon/php-leak/php-7.3.10/a.out)
==25026==    by 0x1EEC55: decltype (__invoke((_S_declval<0ul>)())) std::thread::_Invoker<std::tuple<main::{lambda()#1}> >::_M_invoke<0ul>(std::_Index_tuple<0ul>) (in /home/symcon/php-leak/php-7.3.10/a.out)
==25026== 
==25026== 29,600 bytes in 50 blocks are definitely lost in loss record 31 of 31
==25026==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==25026==    by 0x229A58: __zend_malloc (zend_alloc.c:2903)
==25026==    by 0x531ABE: _pcre2_memctl_malloc_8 (pcre2_context.c:89)
==25026==    by 0x571376: php_pcre2_match_data_create (pcre2_match_data.c:61)
==25026==    by 0x31E8D2: php_pcre_init_pcre2 (php_pcre.c:210)
==25026==    by 0x31E941: zm_globals_ctor_pcre (php_pcre.c:266)
==25026==    by 0x1F01EB: allocate_new_resource (TSRM.c:317)
==25026==    by 0x1F07A0: ts_resource_ex (TSRM.c:375)
==25026==    by 0x1EDF5F: main::{lambda()#1}::operator()() const (in /home/symcon/php-leak/php-7.3.10/a.out)
==25026==    by 0x1EE9EA: void std::__invoke_impl<void, main::{lambda()#1}>(std::__invoke_other, main::{lambda()#1}&&) (in /home/symcon/php-leak/php-7.3.10/a.out)
==25026==    by 0x1EE805: std::__invoke_result<main::{lambda()#1}>::type std::__invoke<main::{lambda()#1}>(std::__invoke_result&&, (main::{lambda()#1}&&)...) (in /home/symcon/php-leak/php-7.3.10/a.out)
==25026==    by 0x1EEC55: decltype (__invoke((_S_declval<0ul>)())) std::thread::_Invoker<std::tuple<main::{lambda()#1}> >::_M_invoke<0ul>(std::_Index_tuple<0ul>) (in /home/symcon/php-leak/php-7.3.10/a.out)
==25026== 
==25026== LEAK SUMMARY:
==25026==    definitely lost: 58,400 bytes in 450 blocks
==25026==    indirectly lost: 3,200 bytes in 100 blocks
==25026==      possibly lost: 0 bytes in 0 blocks
==25026==    still reachable: 1,094 bytes in 20 blocks
==25026==         suppressed: 0 bytes in 0 blocks
==25026== Reachable blocks (those to which a pointer was found) are not shown.
==25026== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==25026== 
==25026== For counts of detected and suppressed errors, rerun with: -v
==25026== ERROR SUMMARY: 9 errors from 9 contexts (suppressed: 0 from 0)


Test script:
---------------
<?php

//Leave it empty


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2019-11-07 11:03 UTC] maroszek at gmx dot net
I there anything i can provide or help to fix this issue?

Thanks!
 [2019-11-07 13:28 UTC] nikic@php.net
-Status: Open +Status: Feedback
 [2019-11-07 13:28 UTC] nikic@php.net
I believe you are just missing a ts_free_thread() at the end of your closure.

With that the only leak I get is:

==24486== 40 bytes in 1 blocks are definitely lost in loss record 1 of 1
==24486==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==24486==    by 0x51D0DEA: tsrm_mutex_alloc (TSRM.c:672)
==24486==    by 0x50232F3: zm_globals_ctor_pcre (php_pcre.c:262)
==24486==    by 0x51CFF36: tsrm_update_active_threads (TSRM.c:284)
==24486==    by 0x51D012F: ts_allocate_id (TSRM.c:325)
==24486==    by 0x529B96C: zend_startup_module_ex (zend_API.c:1850)
==24486==    by 0x529BA49: zend_startup_module_zval (zend_API.c:1874)
==24486==    by 0x52ACD10: zend_hash_apply (zend_hash.c:1812)
==24486==    by 0x529C0CD: zend_startup_modules (zend_API.c:1985)
==24486==    by 0x51D7CA3: php_module_startup (main.c:2330)
==24486==    by 0x537BEC0: php_embed_startup (php_embed.c:108)
==24486==    by 0x537C024: php_embed_init (php_embed.c:198)
 [2019-11-07 13:33 UTC] nikic@php.net
I've fixed the remaining leak mentioned in my last comment in https://github.com/php/php-src/commit/6dcc0b859f5f31729ab3f1e776b067fb338b1978, so now I don't get any leaks anymore.
 [2019-11-07 13:53 UTC] maroszek at gmx dot net
-Status: Feedback +Status: Closed
 [2019-11-07 13:53 UTC] maroszek at gmx dot net
Thanks again! That did it. And thanks for fixing the last one.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sun Dec 22 01:01:30 2024 UTC