Bug #78698 [NEW]: Memory Leak in realpath_cache when using ZTS Embed SAPI

From: Date: Sat, 19 Oct 2019 20:14:26 +0000
Subject: Bug #78698 [NEW]: Memory Leak in realpath_cache when using ZTS Embed SAPI
Groups: php.bugs 
Request: Send a blank email to php-bugs+get-223309@lists.php.net to get a copy of this message
From:             maroszek at gmx dot net
Operating system: Ubuntu
PHP version:      7.3.10
Package:          *General Issues
Bug Type:         Bug
Bug description:Memory Leak in realpath_cache when using ZTS Embed SAPI

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


-- 
Edit bug report at https://bugs.php.net/bug.php?id=78698&edit=1
-- 
Fix committed:                    https://bugs.php.net/fix.php?id=78698&r=fixed
Fixed in release:                 https://bugs.php.net/fix.php?id=78698&r=alreadyfixed
Need backtrace:                   https://bugs.php.net/fix.php?id=78698&r=needtrace
Need Reproduce Script:            https://bugs.php.net/fix.php?id=78698&r=needscript
Try newer version:                https://bugs.php.net/fix.php?id=78698&r=oldversion
Not developer issue:              https://bugs.php.net/fix.php?id=78698&r=support
Expected behavior:                https://bugs.php.net/fix.php?id=78698&r=notwrong
Not enough info:                  https://bugs.php.net/fix.php?id=78698&r=notenoughinfo
Submitted twice:                  https://bugs.php.net/fix.php?id=78698&r=submittedtwice
register_globals:                 https://bugs.php.net/fix.php?id=78698&r=globals
PHP version support discontinued: https://bugs.php.net/fix.php?id=78698&r=phptooold
Daylight Savings:                 https://bugs.php.net/fix.php?id=78698&r=dst
IIS Stability:                    https://bugs.php.net/fix.php?id=78698&r=isapi
Install GNU Sed:                  https://bugs.php.net/fix.php?id=78698&r=gnused
Floating point limitations:       https://bugs.php.net/fix.php?id=78698&r=float
No Zend Extensions:               https://bugs.php.net/fix.php?id=78698&r=nozend
MySQL Configuration Error:        https://bugs.php.net/fix.php?id=78698&r=mysqlcfg


Thread (5 messages)

« previous php.bugs (#223309) next »