php / php/php-src

Method call may leak if releasing EG(This) triggers GC

Open
#13,687 5 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Bug Category: GC Waiting on Author
Dominant language
C
Stars
40.4k
Forks
8.1k
Avg merge
2d 13h
Merged PRs (30d)
96

Description

Description

Method calls may cause their return value to leak if releasing EG(This) triggers GC.

The following code:

<?php

class A {
    public $cycle;
    public function __construct() { $this->cycle = $this; }
}
class B {
    public function get() {
        return new A();
    }
}

$c = new B();
$objs = [];

while (gc_status()['roots']+2 < gc_status()['threshold']) {
    $obj = new stdClass;
    $objs[] = $obj;
}

var_dump($c->get());

Resulted in a memory leak:

Script:  'test.php'
Zend/zend_objects.c(189) :  Freeing 0x00007ffff7a5c840 (56 bytes), script=test.php
=== Total 1 memory leaks detected ===

Here is what is happening:

  • After returning from get(), $c is released, which triggers GC
    • A is removed from buffer, and is not collected because it's referenced by the call stack
  • After returning from var_dump(), zend_vm_stack_free_args() releases A with zval_ptr_dtor_nogc(), so A is not added to the GC buffer
  • At this point nothing references A but itself, and A is not in the GC buffer, so it leaks

I'm not sure how to fix this appart from switching to zval_ptr_dtor().

PHP Version

master

Operating System

No response

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the leak with the test.php example, then inspect the linked zend_vm_def.h call sites around lines 2866 and 4019 and the leak report from Zend/zend_objects.c. Confirm the fix prevents the returned cyclic object from remaining uncollected and that the example no longer reports a memory leak.

Written by the indexing model from the issue text.

Assessment

Tech stack
c, php
Domain
backend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.