#1032 PHP wrapper leaks around t_ouput_helper function.

closed-fixed
Olly Betts
php (58)
5
2009-07-29
2009-07-24
Hitoshi Amano
No

The smallest code to reproduce this problem is here.

==
// example.i

%module example
%include typemaps.i
%{
void foo(int *a) { *a = 1; }
%}
void foo(int *OUTPUT);

==
<?php // test.php

require("example.php");
foo();

==
// example_wrapper.cpp

(snip)

ZEND_NAMED_FUNCTION(_wrap_foo) {
int *arg1 = (int *) 0 ;
int temp1 ;

arg1 = &temp1;
SWIG_ResetError();
if(ZEND_NUM_ARGS() != 0) {
WRONG_PARAM_COUNT;
}

foo(arg1);

{
zval *o;
MAKE_STD_ZVAL(o); // <- *** This ZVAL is never FREE!! ***
ZVAL_LONG(o,temp1);
t_output_helper( &return_value, o );
}
return;
fail:
zend_error(SWIG_ErrorCode(),"%s",SWIG_ErrorMsg());
}
(snip)

==
// stack trace

#0 _emalloc (size=20, __zend_filename=0xb7fda5c2 "example_wrap.cpp", __zend_lineno=1063, __zend_orig_filename=0x0, __zend_orig_lineno=0)
at /home/amachang/Desktop/src/php-5.3.0/Zend/zend_alloc.c:2303
#1 0xb7fda02d in _wrap_foo (ht=0, return_value=0x94556f4, return_value_ptr=0x0, this_ptr=0x0, return_value_used=0) at example_wrap.cpp:1063
#2 0x08217f37 in zend_do_fcall_common_helper_SPEC (execute_data=0x9487538) at /home/amachang/Desktop/src/php-5.3.0/Zend/zend_vm_execute.h:313
#3 0x082184f4 in ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER (execute_data=0x9487538) at /home/amachang/Desktop/src/php-5.3.0/Zend/zend_vm_execute.h:422
#4 0x082175d4 in execute (op_array=0x9455f04) at /home/amachang/Desktop/src/php-5.3.0/Zend/zend_vm_execute.h:104
#5 0x081eb2a5 in zend_execute_scripts (type=8, retval=0x0, file_count=3) at /home/amachang/Desktop/src/php-5.3.0/Zend/zend.c:1188
#6 0x081844ae in php_execute_script (primary_file=0xbfcff8cc) at /home/amachang/Desktop/src/php-5.3.0/main/main.c:2196
#7 0x082ad5b6 in main (argc=4, argv=0xbfcffa24) at /home/amachang/Desktop/src/php-5.3.0/sapi/cli/php_cli.c:1188

The variable "o" is must free when return_value->type is not IS_ARRAY.

I attached patch to fix problem.

thx

Discussion

  • Olly Betts
    Olly Betts
    2009-07-28

    • status: open --> closed-duplicate
     
  • Olly Betts
    Olly Betts
    2009-07-28

    Actually, no it isn't, it just looks very similar at first glance.

     
  • Olly Betts
    Olly Betts
    2009-07-28

    • status: closed-duplicate --> open-accepted
     
  • Olly Betts
    Olly Betts
    2009-07-29

    • status: open-accepted --> closed-fixed
     
  • Olly Betts
    Olly Betts
    2009-07-29

    I made this simpler change instead, which also fixes the problem for me (putting your test in an infinite loop doesn't eat memory with either this patch or yours):

    Index: Lib/php/utils.i

    --- Lib/php/utils.i (revision 11462)
    +++ Lib/php/utils.i (working copy)
    @@ -53,6 +53,7 @@
    }
    if ( (*target)->type == IS_NULL ) {
    REPLACE_ZVAL_VALUE(target,o,1);
    + FREE_ZVAL(o);
    return;
    }
    zval *tmp;

    If that doesn't fix it properly for you, please comment on this ticket.

    Applied in SVN trnk r11464.

     
  • Hitoshi Amano
    Hitoshi Amano
    2009-07-29

    This simpler change fixed the problem. Thanks.