PHP 5.6 static access valgrind issue

php.internals

Derick Rethans

9 years ago
Hi! Through https://bugs.xdebug.org/view.php?id=1185 I ran into a bug in PHP proper. Apparently, this script: <?php class A { static private $a; static public function init() { self::$a = 123; } } A::init(); echo 'succcess!'; And running it with "valgrind php -n index.php", produces: root@debian-8-64bit:/home/derick/xdebug-issue-1185# valgrind php -n index.php ==760== Memcheck, a memory error detector ==760== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. ==760== Using Valgrind-3.10.0 and LibVEX; rerun with -h for copyright info ==760== Command: php -n index.php ==760== ==760== Conditional jump or move depends on uninitialised value(s) ==760== at 0x797992: zend_std_get_static_method (zend_object_handlers.c:1261) ==760== by 0x7B66FE: ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CONST_HANDLER (zend_vm_execute.h:3887) ==760== by 0x7A379F: execute_ex (zend_vm_execute.h:363) ==760== by 0x76E2AF: zend_execute_scripts (zend.c:1341) ==760== by 0x70CC87: php_execute_script (main.c:2613) ==760== by 0x81A990: do_cli (php_cli.c:998) ==760== by 0x431996: main (php_cli.c:1382) ==760== succcess!==760== ==760== HEAP SUMMARY: ==760== in use at exit: 96 bytes in 3 blocks ==760== total heap usage: 19,605 allocs, 19,602 frees, 3,589,979 bytes allocated ==760== ==760== LEAK SUMMARY: ==760== definitely lost: 0 bytes in 0 blocks ==760== indirectly lost: 0 bytes in 0 blocks ==760== possibly lost: 0 bytes in 0 blocks ==760== still reachable: 96 bytes in 3 blocks ==760== suppressed: 0 bytes in 0 blocks ==760== Rerun with --leak-check=full to see details of leaked memory ==760== ==760== For counts of detected and suppressed errors, rerun with: -v ==760== Use --track-origins=yes to see where uninitialised values come from ==760== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0) This is with the latest PHP-5.6 branch, and the GCC that comes with Debian Jessie: root@debian-8-64bit:/home/derick/xdebug-issue-1185# gcc --version gcc (Debian 4.9.2-10) 4.9.2 Annoyingly, I can only produce this on a Debian Jessie (8.6) fresh install, and not on my local machine. I can't seem to find the problem either, but I *can* provide a VM and instructions to reproduce this. Or provide SSH access into it upon request. Anybody wants to try and fix this? I'm going to see whether PHP 7.0 and 7.1 have a similar issue too. cheers, Derick
-- https://derickrethans.nl | https://xdebug.org | https://dram.io Like Xdebug? Consider a donation: https://xdebug.org/donate.php twitter: @derickr and @xdebug

Christoph Becker

9 years ago
Hi Derick! On 09.11.2016 at 15:21, Derick Rethans wrote:
> Hi! > > Through https://bugs.xdebug.org/view.php?id=1185 I ran into a bug in PHP > proper. Apparently, this script: > > <?php > > class A { > static private $a; > > static public function init() { > self::$a = 123; > } > } > > A::init(); > > echo 'succcess!'; > > And running it with "valgrind php -n index.php", produces: > > root@debian-8-64bit:/home/derick/xdebug-issue-1185# valgrind php -n index.php > ==760== Memcheck, a memory error detector > ==760== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. > ==760== Using Valgrind-3.10.0 and LibVEX; rerun with -h for copyright info > ==760== Command: php -n index.php > ==760== > ==760== Conditional jump or move depends on uninitialised value(s) > ==760== at 0x797992: zend_std_get_static_method (zend_object_handlers.c:1261) > ==760== by 0x7B66FE: ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CONST_HANDLER (zend_vm_execute.h:3887) > ==760== by 0x7A379F: execute_ex (zend_vm_execute.h:363) > ==760== by 0x76E2AF: zend_execute_scripts (zend.c:1341) > ==760== by 0x70CC87: php_execute_script (main.c:2613) > ==760== by 0x81A990: do_cli (php_cli.c:998) > ==760== by 0x431996: main (php_cli.c:1382) > ==760== > succcess!==760== > ==760== HEAP SUMMARY: > ==760== in use at exit: 96 bytes in 3 blocks > ==760== total heap usage: 19,605 allocs, 19,602 frees, 3,589,979 bytes allocated > ==760== > ==760== LEAK SUMMARY: > ==760== definitely lost: 0 bytes in 0 blocks > ==760== indirectly lost: 0 bytes in 0 blocks > ==760== possibly lost: 0 bytes in 0 blocks > ==760== still reachable: 96 bytes in 3 blocks > ==760== suppressed: 0 bytes in 0 blocks > ==760== Rerun with --leak-check=full to see details of leaked memory > ==760== > ==760== For counts of detected and suppressed errors, rerun with: -v > ==760== Use --track-origins=yes to see where uninitialised values come from > ==760== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0) > > This is with the latest PHP-5.6 branch, and the GCC that comes with > Debian Jessie: > > root@debian-8-64bit:/home/derick/xdebug-issue-1185# gcc --version > gcc (Debian 4.9.2-10) 4.9.2 > > > Annoyingly, I can only produce this on a Debian Jessie (8.6) fresh install, and > not on my local machine. I can't seem to find the problem either, but I *can* > provide a VM and instructions to reproduce this. Or provide SSH access > into it upon request. > > Anybody wants to try and fix this? I'm going to see whether PHP 7.0 and > 7.1 have a similar issue too.
zend_std_get_static_method() declares use_heap[1] (if there's support for alloca), but doesn't initialize it with SET_ALLOCA_FLAG()[2]. It seems to me that ALLOCA_FLAG()[3] should be defined like so: # define ALLOCA_FLAG(name) \ zend_bool name = 0; [1] <http://lxr.php.net/xref/PHP-5.6/Zend/zend_object_handlers.c#1184> [2] <http://lxr.php.net/source/xref/PHP-5.6/Zend/zend.h#200> [3] <http://lxr.php.net/source/xref/PHP-5.6/Zend/zend.h#198>
-- Christoph M. Becker

Derick Rethans

9 years ago
On Wed, 9 Nov 2016, Christoph M. Becker wrote:
> On 09.11.2016 at 15:21, Derick Rethans wrote:
<snip>
> > And running it with "valgrind php -n index.php", produces: > > > > root@debian-8-64bit:/home/derick/xdebug-issue-1185# valgrind php -n index.php > > ==760== Memcheck, a memory error detector > > ==760== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. > > ==760== Using Valgrind-3.10.0 and LibVEX; rerun with -h for copyright info > > ==760== Command: php -n index.php > > ==760== > > ==760== Conditional jump or move depends on uninitialised value(s) > > ==760== at 0x797992: zend_std_get_static_method (zend_object_handlers.c:1261) > > ==760== by 0x7B66FE: ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CONST_HANDLER (zend_vm_execute.h:3887) > > ==760== by 0x7A379F: execute_ex (zend_vm_execute.h:363) > > ==760== by 0x76E2AF: zend_execute_scripts (zend.c:1341) > > ==760== by 0x70CC87: php_execute_script (main.c:2613) > > ==760== by 0x81A990: do_cli (php_cli.c:998) > > ==760== by 0x431996: main (php_cli.c:1382) > > ==760==
> zend_std_get_static_method() declares use_heap[1] (if there's support > for alloca), but doesn't initialize it with SET_ALLOCA_FLAG()[2]. It > seems to me that ALLOCA_FLAG()[3] should be defined like so: > > # define ALLOCA_FLAG(name) \ > zend_bool name = 0;
That sounds about right - Dmitry, Nikita?
> > I'm going to see whether PHP 7.0 and 7.1 have a similar issue too.
It seems like there is a similar issue in PHP 7.0 and 7.1 too, looking at the source. cheers, Derick

Nikita Popov

9 years ago
On Wed, Nov 9, 2016 at 4:09 PM, Derick Rethans <derick@php.net> wrote:
> On Wed, 9 Nov 2016, Christoph M. Becker wrote: > > > On 09.11.2016 at 15:21, Derick Rethans wrote: > > <snip> > > > > And running it with "valgrind php -n index.php", produces: > > > > > > root@debian-8-64bit:/home/derick/xdebug-issue-1185# valgrind php > -n index.php > > > ==760== Memcheck, a memory error detector > > > ==760== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward > et al. > > > ==760== Using Valgrind-3.10.0 and LibVEX; rerun with -h for > copyright info > > > ==760== Command: php -n index.php > > > ==760== > > > ==760== Conditional jump or move depends on uninitialised value(s) > > > ==760== at 0x797992: zend_std_get_static_method > (zend_object_handlers.c:1261) > > > ==760== by 0x7B66FE: ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CONST_HANDLER > (zend_vm_execute.h:3887) > > > ==760== by 0x7A379F: execute_ex (zend_vm_execute.h:363) > > > ==760== by 0x76E2AF: zend_execute_scripts (zend.c:1341) > > > ==760== by 0x70CC87: php_execute_script (main.c:2613) > > > ==760== by 0x81A990: do_cli (php_cli.c:998) > > > ==760== by 0x431996: main (php_cli.c:1382) > > > ==760== > > > zend_std_get_static_method() declares use_heap[1] (if there's support > > for alloca), but doesn't initialize it with SET_ALLOCA_FLAG()[2]. It > > seems to me that ALLOCA_FLAG()[3] should be defined like so: > > > > # define ALLOCA_FLAG(name) \ > > zend_bool name = 0; > > That sounds about right - Dmitry, Nikita? >
This shouldn't be a problem. alloca is only used in the !key branches, in which case the flag is initialized by do_alloca.

Derick Rethans

9 years ago
On Wed, 9 Nov 2016, Nikita Popov wrote:
> On Wed, Nov 9, 2016 at 4:09 PM, Derick Rethans <derick@php.net> wrote: > > > On Wed, 9 Nov 2016, Christoph M. Becker wrote: > > > > > On 09.11.2016 at 15:21, Derick Rethans wrote: > > > > <snip> > > > > > > And running it with "valgrind php -n index.php", produces: > > > > > > > > root@debian-8-64bit:/home/derick/xdebug-issue-1185# valgrind php -n index.php > > > > ==760== Memcheck, a memory error detector > > > > ==760== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. > > > > ==760== Using Valgrind-3.10.0 and LibVEX; rerun with -h for copyright info > > > > ==760== Command: php -n index.php > > > > ==760== > > > > ==760== Conditional jump or move depends on uninitialised value(s) > > > > ==760== at 0x797992: zend_std_get_static_method (zend_object_handlers.c:1261) > > > > ==760== by 0x7B66FE: ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CONST_HANDLER (zend_vm_execute.h:3887) > > > > ==760== by 0x7A379F: execute_ex (zend_vm_execute.h:363) > > > > ==760== by 0x76E2AF: zend_execute_scripts (zend.c:1341) > > > > ==760== by 0x70CC87: php_execute_script (main.c:2613) > > > > ==760== by 0x81A990: do_cli (php_cli.c:998) > > > > ==760== by 0x431996: main (php_cli.c:1382) > > > > ==760== > > > > > zend_std_get_static_method() declares use_heap[1] (if there's support > > > for alloca), but doesn't initialize it with SET_ALLOCA_FLAG()[2]. It > > > seems to me that ALLOCA_FLAG()[3] should be defined like so: > > > > > > # define ALLOCA_FLAG(name) \ > > > zend_bool name = 0; > > > > That sounds about right - Dmitry, Nikita? > > This shouldn't be a problem. alloca is only used in the !key branches, in > which case the flag is initialized by do_alloca.
However, it is a problem as my valgrind note says. However, I wouldn't be surprised if this was a (Debian) GCC bug. I can't reproduce this when I change -O2 to -O0 in the Makefile. In the past, I have found a similar issue in Xdebug, where it was really something Xdebug was doing wrong, but in a very vague way (https://github.com/xdebug/xdebug/commit/c36ea38141cb9403ff4bf72602fcf4ae62e5ba1e). However, right now, it's a bug with this GCC version. cheers, Derick
-- https://derickrethans.nl | https://xdebug.org | https://dram.io Like Xdebug? Consider a donation: https://xdebug.org/donate.php twitter: @derickr and @xdebug