Description
TL;DR; Weird thing happens with php8+ when using Amazon Linux 2. Using docker images from php for php8+ the same test pasts. Issue appears to be related to the specific packages installed not php as a whole. BUT it does also show some odd things happening by moving code about.
I'm not sure how to debug php-meminfo itself, but I have a really odd one that I was able to replicate down to a small test. The test consists of TestClass
in which I want to use the static Current()
method to get a single instance of the class.
<?php
class TestClass
{
protected static $CurrentInstance;
public static function Current() : TestClass
{
// Check if there is an instance created already.
if (isset(static::$CurrentInstance))
{
return static::$CurrentInstance;
}
// If not create and return it.
static::$CurrentInstance = new TestClass();
return static::$CurrentInstance;
}
}
$some_bool = false;
if ($some_bool === true)
{
$test = TestClass::Current();
}
meminfo_dump(fopen('/tmp/my_dump_file.json', 'w'));
echo time();
This will result in SIGSEGV which will result in apache giving a 503 response. But things get really odd really quick.
If you change
if ($some_bool === true)
{
$test = TestClass::Current();
}
to
if ($some_bool === true)
{
TestClass::Current();
}
then the code will work. Maybe something about having a reference to the variable? But it's odd because the code will never execute as $some_bool
is false.
Another oddity is if you move the declaration outside of the if then it will also work as expected.
$test = TestClass::Current();
if ($some_bool === true)
{
}
EDIT: I also just found it has nothing to do with the static variable. The new minimum test case is
<?php
class TestClass
{
}
$some_bool = false;
if ($some_bool === true)
{
$test = new TestClass();
}
meminfo_dump(fopen('/tmp/my_dump_file.json', 'w'));
echo time();
I should have also included specs. This is running on a Amazon Linux 2 EC2 instance. php version is
# php -v
PHP 8.0.28 (cli) (built: Mar 28 2023 17:41:50) ( NTS )
Copyright (c) The PHP Group
Zend Engine v4.0.28, Copyright (c) Zend Technologies
with Zend OPcache v8.0.28, Copyright (c), by Zend Technologies
As for php-meminfo, I built it from the current master source.
EDIT 2:
This can be replicated without the TestClass
<?php
$some_bool = false;
if ($some_bool === true)
{
$test = new stdClass();
}
meminfo_dump(fopen('/tmp/my_dump_file.json', 'w'));
echo time();
EDIT 3:
Looks like maybe it has something to do with code being removed when executed or something.
This works
<?php
$some_bool = false;
if ($some_bool === false)
{
$test = new stdClass();
}
meminfo_dump(fopen('/tmp/my_dump_file.json', 'w'));
echo time();
This does not
<?php
$some_bool = false;
if ($some_bool === true)
{
$test = new stdClass();
}
meminfo_dump(fopen('/tmp/my_dump_file.json', 'w'));
echo time();
But in saying that this works and it shouldn't according to the above example
<?php
$some_bool = true;
if (false)
{
$test = new stdClass();
}
meminfo_dump(fopen('/tmp/my_dump_file.json', 'w'));
echo time();
But then this also works
<?php
$some_bool = false;
$test = null;
if ($some_bool === true)
{
$test = new stdClass();
}
meminfo_dump(fopen('/tmp/my_dump_file.json', 'w'));
echo time();
You can also get this to fail with primatives.
<?php
$some_bool = false;
if ($some_bool === true)
{
$test = 1;
}
meminfo_dump(fopen('/tmp/my_dump_file.json', 'w'));
echo time();