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

オープン
#13,687 コメント 5 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

評価

難易度
4/5
見積もり時間
3〜5日
初心者へのやさしさ
38/100
issue の種類
バグ
明瞭さ
おおむね明確
活発さ
停滞
技術スタック
c, php
領域
backend

調査の方向性

test.php の例でリークを再現し、続いて 2866 行目と 4019 行目付近にある、リンクされた zend_vm_def.h の呼び出し箇所と、Zend/zend_objects.c のリークレポートを調べます。修正によって返された循環オブジェクトが回収されないまま残らなくなり、例でメモリリークが報告されなくなることを確認します。

索引モデルが issue の本文から書いたものです。

説明

Bug Category: GC Waiting on Author
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

主要言語
C
スター
40.4k
フォーク
8.2k
平均マージ
2日 15時間
マージ済み PR(30日)
103

コントリビューションガイド

コントリビューションガイドを開く

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

php/php-src のほかの issue

php/php-src の issue をすべて見る

似ている issue

C の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。