Skip to content

ext/intl: Fix memory leak in MessageFormatter::format() #11658

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from

Conversation

Girgias
Copy link
Member

@Girgias Girgias commented Jul 10, 2023

Found while investigating #11614 this is probably present in all versions of PHP and we need a regression test, and probably inform about the proper reason.

@danog do you know which test in https://github.com/zoonru/Valinor might have caused this leak to happen?

@danog
Copy link
Contributor

danog commented Jul 10, 2023

Quite possibly it's tests/Unit/Utility/String/StringFormatterTest.php

@Girgias Girgias changed the base branch from master to PHP-8.1 July 10, 2023 12:25
@Girgias Girgias changed the title W.I.P. Fix memory leak in ext/intl ext/intl: Fix memory leak in MessageFormatter::format() Jul 10, 2023
@Girgias Girgias marked this pull request as ready for review July 10, 2023 12:26
@Girgias Girgias requested a review from nielsdos July 10, 2023 15:33
Copy link
Member

@nielsdos nielsdos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't reproduce the memory leak. After reverting your patch and executing the same test I don't get leaks with Valgrind.
You seem to have added an else case for "Creating message formatter failed", but this case isn't actually tested in the testcase?
I'm also not sure about that umsg_close, why do we need it? This is the only error-handling place where we use that in PHP AFAICT?

@Girgias
Copy link
Member Author

Girgias commented Jul 11, 2023

I can't reproduce the memory leak. After reverting your patch and executing the same test I don't get leaks with Valgrind. You seem to have added an else case for "Creating message formatter failed", but this case isn't actually tested in the testcase? I'm also not sure about that umsg_close, why do we need it? This is the only error-handling place where we use that in PHP AFAICT?

I was hitting it with ASAN:

./configure -C CC=gcc CFLAGS="-DPROFITABILITY_CHECKS=0 -DZEND_RC_DEBUG=1 -DZEND_VERIFY_FUNC_INFO=1 -DZEND_TRACK_ARENA_ALLOC=1 -ggdb3" --enable-address-sanitizer --enable-undefined-sanitizer --enable-debug --enable-tokenizer --enable-opcache --enable-zend-test --enable-dl-test=shared   --enable-pcntl --enable-mbstring --enable-fpm --enable-posix --enable-bcmath --enable-calendar --enable-ctype --enable-exif   --enable-fileinfo --enable-filter --enable-ftp --enable-gd --enable-session --enable-sockets   --enable-sysvmsg --enable-shmop --enable-sysvsem --enable-sysvshm   --enable-dba --with-qdbm --with-cdb --enable-flatfile --enable-inifile --with-lmdb --with-tcadb --with-db4 --with-zip --with-zlib --with-bz2   --with-curl --with-ffi --with-gmp --with-tidy --with-enchant --with-openssl --with-sodium   --with-libxml --enable-dom --enable-simplexml --enable-xml --enable-xmlreader --enable-xmlwriter --with-xsl --enable-soap   --with-sqlite3 --with-mysqli --with-unixODBC --enable-pdo --with-pdo-firebird --with-pdo-mysql --with-pdo-pgsql --with-pdo-sqlite --with-pgsql   --with-iconv --enable-phar --with-pspell --with-readline --enable-intl

And the following test command:

make -j22 && make test TEST_PHP_ARGS="--asan -q -j22 -d opcache.jit=0 -d opcache.enable=1 -d opcache.enable_cli=1 -d opcache.file_update_protection=0 -d opcache.jit_buffer_size=1M -x" TESTS="ext/intl/tests/"

I think part of the reason why we don't normally use that, is that the errors will get and formatter will get closed/destructed when the object's refcount hits 0 as those things are stored within the object.

However, this method is static and creates an "object" on the fly which we were not freeing.

The ASAN stack traced showed the malloc happening in ICU 72 for me.

Copy link
Member

@nielsdos nielsdos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I tried with Valgrind and couldn't reproduce. ASAN lets me reproduce it.
Code looks good and does indeed fix it.

@Girgias Girgias closed this in 536dbd7 Jul 12, 2023
@Girgias Girgias deleted the intl-memleak branch July 12, 2023 14:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants