php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #78046 pcntl_async_signals breaks down magic getter
Submitted: 2019-05-21 09:45 UTC Modified: 2019-05-22 07:50 UTC
Votes:1
Avg. Score:3.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:0 (0.0%)
From: toxbyte at gmail dot com Assigned:
Status: Open Package: PCNTL related
PHP Version: 7.3.5 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: toxbyte at gmail dot com
New email:
PHP Version: OS:

 

 [2019-05-21 09:45 UTC] toxbyte at gmail dot com
Description:
------------
When use "pcntl_async_signals(true)" and try to access the magic property from async signal handler and regular way in same time, get error "Undefined property". 

PHP 7.1 7.2 7.3:
docker run -it --rm -v "$PWD":/app php:7.1.29-cli sh -c "docker-php-ext-install -j"$(getconf _NPROCESSORS_ONLN)" pcntl && php /app/test-magic.php"
docker run -it --rm -v "$PWD":/app php:7.2.18-cli sh -c "docker-php-ext-install -j"$(getconf _NPROCESSORS_ONLN)" pcntl && php /app/test-magic.php"
docker run -it --rm -v "$PWD":/app php:7.3.5-cli sh -c "docker-php-ext-install -j"$(getconf _NPROCESSORS_ONLN)" pcntl && php /app/test-magic.php"

Test script:
---------------
<?php //test-magic.php
$obj = new TestMagic;
$childrenCount = 100;
$completed = 0;

pcntl_async_signals(true);

set_error_handler(static function (int $errNo, string $errStr) {
    throw new \ErrorException("ERROR #{$errNo}: {$errStr}");
});

pcntl_signal(SIGINT, static function () {exit;});
pcntl_signal(SIGTERM, static function () {exit;});
pcntl_signal(SIGCHLD, static function () use ($obj, &$completed) {
    $completed++;
    echo "ASYNC ACCESS #{$completed} ";
    echo "{$obj->x}\n";
});

$inRun = 0;
while (++$inRun <= $childrenCount) {
    proc_open('sleep ' . (random_int(1, 999) / 1000), [['pipe', 'r'], ['pipe', 'w'], ['pipe', 'w']], $pipes);
}

while ($completed < $childrenCount) {
    echo "BLOCKING ACCESS #{$completed} ";
    echo "{$obj->x}\n";
}

/** @property $x */
class TestMagic
{
    public function __set($name, $value)
    {
        return null;
    }

    public function __get($name)
    {
        return 'OK';
    }

    public function __isset($name)
    {
        return true;
    }
}

// ...
// BLOCKING ACCESS #5 OK
// BLOCKING ACCESS #5 ASYNC ACCESS #6 
// Fatal error: Uncaught ErrorException: ERROR #8: Undefined property: TestMagic::$x in /app/test-magic.php:9
// Stack trace:
// #0 /app/test-magic.php(17): {closure}(8, 'Undefined prope...', '/app/test-magic...', 17, Array)
// #1 /app/test-magic.php(41): {closure}(17, Array)
// #2 /app/test-magic.php(27): TestMagic->__get('x')
// #3 {main}
//   thrown in /app/test-magic.php on line 9
// Segmentation fault (core dumped)



Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2019-05-22 07:50 UTC] nikic@php.net
Not sure what we can do about this. This is in line with the usual semantics of accessing properties within __get, even though here it happens through a signal handler executed inside __get.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 21 20:01:29 2024 UTC