php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #64195 clone object with circular reference cause segfault
Submitted: 2013-02-12 11:33 UTC Modified: 2013-02-12 11:49 UTC
From: vovan-ve at yandex dot ru Assigned:
Status: Not a bug Package: Class/Object related
PHP Version: 5.4.11 OS: linux
Private report: No CVE-ID: None
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 !
Your email address:
MUST BE VALID
Solve the problem:
22 - 15 = ?
Subscribe to this entry?

 
 [2013-02-12 11:33 UTC] vovan-ve at yandex dot ru
Description:
------------
There are two objects of the same class. Both objects has a property. There are
circular object reference: $a->prop === $b && $b->prop === $a. The class has
a __clone() handler which clones object in that property.

So, clonning such object cause segfault.

Yes, described architecture is ugly, but this is just for test.

Test code:

----
    class A {
        public $prop;

        public function __clone() {
            $this->prop = clone $this->prop;
        }
    }

    // create two objects
    $a = new A();
    $b = new A();

    // create circular reference
    $b->prop = $a;
    $a->prop = $b;

    // see short dump with *RECURSION* marker
    print_r($a);

    // now make a problem
    $c = clone $a;

    // never will reach here
    print_r($c);
----

5.5.0.a2, 5.4.11, 5.3.20 and 5.2.17 crashes with segfault. It is infinite
recursion. Also Fatal Error can be emited about memory allocation when small
memory_limit is set (1M for example).

Unlimited recursion for a simple function cause a fatal error, so the bug always should cause the same fatal error.

Test script:
---------------
class A {
    public $prop;

    public function __clone() {
        $this->prop = clone $this->prop;
    }
}

$a = new A();
$b = new A();

$b->prop = $a;
$a->prop = $b;

print_r($a);

$c = clone $a;
print_r($c);

Expected result:
----------------
A Object
(
    [prop] => A Object
        (
            [prop] => A Object
 *RECURSION*
        )

)

Fatal error: Allowed memory size of ... bytes exhausted (tried to allocate ... bytes)

Actual result:
--------------
A Object
(
    [prop] => A Object
        (
            [prop] => A Object
 *RECURSION*
        )

)
Segmentation fault (core dumped)

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2013-02-12 11:49 UTC] johannes@php.net
-Status: Open +Status: Not a bug
 [2013-02-12 11:49 UTC] johannes@php.net
Thank you for taking the time to write to us, but this is not
a bug. Please double-check the documentation available at
http://www.php.net/manual/ and the instructions on how to report
a bug at http://bugs.php.net/how-to-report.php

Infinite recursion leads to a stack overflow (clone calls clone, calls clone, calls clone, ...) we have no good way to handle this.
 [2013-02-12 12:04 UTC] vovan-ve at yandex dot ru
Ok. Why I cannot get same error for simple function recursion with memory_limit = -1?

    $ php -d memory_limit=-1 -r 'function f() { f(); } f();'

I has x64 with 8 GB RAM. For thise short test I see large memory usage (with some system freezes), but there are no stack overflow. The subject test code goes to segfault too quickly, I think. Are you really sure there are no errors here?
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Oct 31 23:01:28 2024 UTC