php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #68358 memory leak with custom get_method/call_method object handlers
Submitted: 2014-11-05 23:18 UTC Modified: 2021-08-12 11:02 UTC
Votes:1
Avg. Score:3.0 ± 0.0
Reproduced:0 of 1 (0.0%)
From: stesie at brokenpipe dot de Assigned: nikic (profile)
Status: Closed Package: Scripting Engine problem
PHP Version: 5.6.2 OS: irrelevant
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: stesie at brokenpipe dot de
New email:
PHP Version: OS:

 

 [2014-11-05 23:18 UTC] stesie at brokenpipe dot de
Description:
------------
This is just a minimal example, demonstrating a memory leak I found writing/debugging a php extension.

I have custom get_method/call_method handlers on a class exported by the extension to allow dispatching arbitrary calls off php.

However every direct function call leaks a reference on the object itself;
while a call using call_user_func does *not*.

I wrote a minimal php "hello" extension, which demonstrates the problem, available at https://gist.github.com/stesie/40d9ab136bea473a16ac
It exports a Hello class, which returns this_ptr->refcount__gc on any method call.

Each time I call $foo->blar() the refcount__gc is incremented once more then decremented.  (i.e. leaks a ref to the object)

If I call_user_func([ $foo, 'blar']) however, which I would expect to behave identical, there's no refcount__gc leak.


I have not digged further into Zend internals, let me know if that would help.
... or if I'm completely off or doing it wrong :)


cheers
  ~stesie

Test script:
---------------
<?php
 
$foo = new Hello();
var_dump($foo);
 
echo "--- direct method call ---\n";
var_dump($foo->blar());
var_dump($foo->blar());
var_dump($foo->blar());
 
echo "--- call_user_func calls ---\n";
var_dump(call_user_func([ $foo, 'blar' ]));
var_dump(call_user_func([ $foo, 'blar' ]));
var_dump(call_user_func([ $foo, 'blar' ]));

Expected result:
----------------
successing direct method calls should not increment refcount__gc

Actual result:
--------------
object(Hello)#1 (0) {
}
--- direct method call ---
int(2)
int(3)
int(4)
--- call_user_func calls ---
int(6)
int(6)
int(6)
[Wed Nov  5 22:40:08 2014]  Script:  '/tmp/40d9ab136bea473a16ac/foo.php'
/usr/local/src/php-5.6.2/Zend/zend_vm_execute.h(944) :  Freeing 0x7FFFF7FE2578 (32 bytes), script=/tmp/40d9ab136bea473a16ac/foo.php
=== Total 1 memory leaks detected ===
[Inferior 1 (process 1711) exited normally]


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2021-08-12 11:02 UTC] nikic@php.net
-Status: Open +Status: Closed -Assigned To: +Assigned To: nikic
 [2021-08-12 11:02 UTC] nikic@php.net
Closing this issue as the call_method() handler is long since gone, and this is instead handled using VIA_HANDLER/VIA_TRAMPOLINE get_method() handlers, so this isn't relevant anymore. Not aware of any leaks with get_method().
 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Mon Jul 07 01:01:34 2025 UTC