php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #78643 Random memory allocation failure in APCU
Submitted: 2019-10-08 00:03 UTC Modified: 2019-10-14 15:45 UTC
From: houman dot bakhtiari at groupe-gts dot fr Assigned:
Status: Verified Package: APC (PECL)
PHP Version: 7.3.10 OS: php:7.3.10-fpm-buster
Private report: No CVE-ID: None
View Add Comment Developer Edit
Anyone can comment on a bug. Have a simpler test case? Does it work for you on a different platform? Let us know!
Just going to say 'Me too!'? Don't clutter the database with that please — but make sure to vote on the bug!
Your email address:
MUST BE VALID
Solve the problem:
44 + 15 = ?
Subscribe to this entry?

 
 [2019-10-08 00:03 UTC] houman dot bakhtiari at groupe-gts dot fr
Description:
------------
Here docker stack :
----------
FROM php:7.3.10-fpm-buster

RUN pecl install apcu \
    && echo "extension=apcu.so" > /usr/local/etc/php/conf.d/apcu.ini
    

WORKDIR /var/www

EXPOSE 9000
CMD ["php-fpm"]




Case 1 : php.ini [CRASH 1]
-------------------
error_reporting = E_ALL & ~E_NOTICE & ~E_DEPRECATED
output_buffering = Off
display_errors = On
apc.shm_size=80M
apc.entries_hint=5000



Case 2 : php.ini [CRASH 2]
-------------------
error_reporting = E_ALL & ~E_NOTICE & ~E_DEPRECATED
output_buffering = Off
display_errors = On
apc.shm_size=200M
apc.entries_hint=5000

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

set_time_limit(0);

for ($i = 1; $i <= 2000; $i++)
{
    apcu_store('session_' . $i, str_pad('', mt_rand(10000, 30000)));
}

$lasts_news = str_pad('', 5000000);

$count_iteration = 0;
while (true)
{
    $i = mt_rand(1, 2000);
    $temoin = apcu_store('session_' . $i, apcu_fetch('session_' . $i));

    if ($temoin === false)
    {
        throw new \Exception('Unable to store session '.$i.' AT iteration '.$count_iteration);
    }

    $temoin = apcu_store('lasts_news', $lasts_news);

    if ($temoin === false)
    {
        throw new \Exception('[CRASH 2] Unable to store lasts news AT iteration ' . $count_iteration);
    }

    $cache_info = apcu_cache_info();
    if (sizeof($cache_info['cache_list']) < 10)
    {
        throw new \Exception('[CRASH 1] APC LIST EMPTY AT iteration ' . $count_iteration);
    }
    $count_iteration++;
}


Expected result:
----------------
Hello, this script should loop indefinitely (stable data length and keys count).

In case 1 (low memory), after some loops, it empties the cache list.
In case 2 (more memory), after some loops, it refuses to store big entry.

Thanks to the whole PHP team for your great work in PHP enhancements.

Actual result:
--------------
Instead of looping, in the case 1 (apc.shm_size=80M) :
Fatal error: Uncaught Exception: [CRASH 1] APC LIST EMPTY AT iteration 96 in /var/www/html/members_area/www/public/crash_reproduction.php:33 Stack trace: #0 {main} thrown in /var/www/html/members_area/www/public/crash_reproduction.php on line 33

Instead of looping, in the case 2 (apc.shm_size=200M) :
Fatal error: Uncaught Exception: [CRASH 2] Unable to store lasts news AT iteration 576 in /var/www/html/members_area/www/public/crash_reproduction.php:27 Stack trace: #0 {main} thrown in /var/www/html/members_area/www/public/crash_reproduction.php on line 27

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2019-10-14 15:45 UTC] nikic@php.net
-Status: Open +Status: Verified
 [2019-10-14 15:45 UTC] nikic@php.net
This is a memory fragmentation issue. Bumping BEST_FIT_LIMIT to a higher value mitigates it somewhat (the failure occurs at higher iteration), but doesn't fix the problem.

This either needs a better SMA allocator, or a mechanism to defragment memory.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Apr 20 13:01:29 2024 UTC