又发现amfext的几处内存泄漏的bug

 amfext的bug已经不知道发现第几次了,这次的bug主要是在使用脚本进行压力测试时发现程序内存会一直增长,最终定位到amfext,如果是以php-cgi方式运行的话,一次请求不会有多次amf_encode和amf_decode调用,因此问题不是很大,因为amfext遵守了php扩展的开发方法,使用了emalloc来分配 内存,因此在RSHUTDOWN时会自动清理,但是如果是用脚本的话,程序很快就会因为内存持续增长也挂掉。

加上与之前amfext的修改,patch如下

 

--- amfext-0.9.2/amf.c 2008-07-18 18:28:36.000000000 +0800
+++ amfext/amf.c 2011-12-01 13:33:12.000000000 +0800
@@ -137,7 +137,8 @@ static void amf_zval_dtor(void *p)

 static void amf_class_dtor(void *p)

 {

  zval **zval_ptr = (zval**)p;

- zval_dtor(*zval_ptr);

+ //zval_dtor(*zval_ptr);

+ zval_ptr_dtor(zval_ptr);

 }

 

 /**  context of serialization */

@@ -473,9 +474,9 @@ static void amf_serialize_output_get(amf
 {

  amf_string_part * cur,* head;

  char * cp,*bcp;

- ZVAL_EMPTY_STRING(result);

  if(buf->length == 0)

  {

+  ZVAL_EMPTY_STRING(result);

   return;

  }

  cp = bcp = guard_emalloc(buf->length);

@@ -510,6 +511,7 @@ static void amf_serialize_output_get(amf
  }

  while(cur != head);

  ZVAL_STRINGL(result, bcp, buf->length,1);

+ efree(bcp);

 }

 

 /**  destructor of the buffer */

@@ -557,9 +559,9 @@ typedef amf_serialize_output_t *amf_seri
 /**  initializes a zval to a HashTable of zval with a possible number of items */

 static int amf_array_init(zval *arg, int count TSRMLS_DC)

 {

- ALLOC_HASHTABLE_REL(arg->value.ht);

+ ALLOC_HASHTABLE(arg->value.ht);

 

- zend_hash_init(arg->value.ht, count, NULL, ZVAL_PTR_DTOR, 0 ZEND_FILE_LINE_RELAY_CC);

+ zend_hash_init(arg->value.ht, count, NULL, ZVAL_PTR_DTOR, 0);

  arg->type = IS_ARRAY;

  return SUCCESS;

 }

@@ -844,7 +846,7 @@ static inline void amf_write_zstring(amf
 

   buf->last_chunk->size = 1;  /*  zval chun */

   buf->last_chunk->zv = zstr;

-  ZVAL_ADDREF(zstr);

+  Z_ADDREF_P(zstr);

   buf->chunks++;

   buf->left_in_part -= sizeof(amf_string_chunk);

 

@@ -1185,7 +1187,7 @@ static void amf3_serialize_object(amf_se
   int resultType = AMFC_TYPEDOBJECT;

   int resultValueLength = 0;

   zval** resultValue = struc;

-  int deallocResult = (*struc)->refcount;

+  int deallocResult = Z_REFCOUNT_PP(struc);

 

   resultType = amf_perform_serialize_callback(struc, &className,&classNameLen,&resultValue,var_hash TSRMLS_CC);

   

@@ -2390,6 +2392,7 @@ PHP_FUNCTION(amf_encode)

   tpbuf = (amf_serialize_output) zend_fetch_resource( zzOutputSB TSRMLS_CC, -1, PHP_AMF_STRING_BUILDER_RES_NAME, NULL, 1, amf_serialize_output_resource_reg); 

   if(tpbuf != NULL)

   {

+   amf_serialize_output_dtor(pbuf);

    pbuf = tpbuf;

    asSB = 1;

     /* ZVAL_ADDREF(*zzOutputSB) */

@@ -2429,7 +2432,7 @@ PHP_FUNCTION(amf_encode)

  }

 

   /*  deallocate if it was wast */

- if(asSB == 1)

+ if(asSB != 1)

  {

   amf_serialize_output_dtor(&buf);

  }

@@ -2440,8 +2443,8 @@ PHP_FUNCTION(amf_encode)

  RETURN_STRINGL(membuf, memsize, 1);

  php_stream_close(pbuf);

  }

- amf_SERIALIZE_DTOR(var_hash,zzCallback)

 #endif

+ amf_SERIALIZE_DTOR(var_hash,zzCallback)

 }

 

 /*  Decoding {{{1*/

@@ -2670,7 +2673,7 @@ static int amf3_read_string(zval **rval,
   }

   else

   {

-   newval->refcount--;

+   Z_DELREF_P(newval);

   }

   *rval = newval;

  }

@@ -2772,6 +2775,7 @@ static int amf_read_objectdata(zval **rv
    break;

   }

   MAKE_STD_ZVAL(zValue);

+  zValue->type = 0;

   if(amf_var_unserialize(&zValue,p, max, var_hash TSRMLS_CC) == FAILURE)

   {

    php_error_docref(NULL TSRMLS_CC, E_NOTICE, "amf cannot unserialize key <%s>",Z_STRVAL_P(zName));  

@@ -2824,7 +2828,7 @@ static int amf_read_objectdata(zval **rv
  {

   if(zClassname != NULL)

   {

-   ZVAL_ADDREF(zClassname);

+   Z_ADDREF_P(zClassname);

    add_assoc_zval(*rval, "_explicitType",zClassname);

   }

  }

@@ -2859,6 +2863,7 @@ static int amf3_unserialize_var(zval **r
  case AMF3_NUMBER:

   ZVAL_DOUBLE(*rval, amf_read_double(p, max, var_hash)); break;

  case AMF3_STRING:

+  zval_ptr_dtor(rval);

   if(amf3_read_string(rval, p, max, 1, AMF_STRING_AS_TEXT,var_hash TSRMLS_CC) == FAILURE)

   {

    php_error_docref(NULL TSRMLS_CC, E_NOTICE, "amf cannot lookup string");

@@ -2906,8 +2911,8 @@ static int amf3_unserialize_var(zval **r
   {

    int iIndex;

    int maxIndex = handle >> 1;

-   HashTable * htOutput = HASH_OF(*rval);

    amf_array_init(*rval, maxIndex TSRMLS_CC);

+   HashTable * htOutput = HASH_OF(*rval);

     /* zval_add_ref(rval) */

    amf_put_in_cache(&(var_hash->objects),*rval);

 

@@ -2927,6 +2932,7 @@ static int amf3_unserialize_var(zval **r
      break;

     }

     MAKE_STD_ZVAL(zValue);

+    zValue->type = 0;

     if(amf3_unserialize_var(&zValue,p,max, var_hash TSRMLS_CC) == FAILURE)

     {

      php_error_docref(NULL TSRMLS_CC, E_NOTICE, "amf cannot unserialize key %s",Z_STRVAL_P(zKey));

@@ -2967,6 +2973,7 @@ static int amf3_unserialize_var(zval **r
     {

      zval * zValue;

      MAKE_STD_ZVAL(zValue)

+     zValue->type = 0;

      if(amf3_unserialize_var(&zValue,p,max,var_hash TSRMLS_CC) == FAILURE)

      {

       zval_ptr_dtor(&zValue);

@@ -3045,7 +3052,7 @@ static int amf3_unserialize_var(zval **r
     MAKE_STD_ZVAL(zClassDef);

     amf_array_init(zClassDef,nClassMemberCount+2 TSRMLS_CC);

     add_next_index_long(zClassDef,(bTypedObject?1:0)|nClassMemberCount << AMF_CLASS_MEMBERCOUNT_SHIFT |iDynamicObject|iExternalizable);

-    ZVAL_ADDREF(zClassname);

+    Z_ADDREF_P(zClassname);

     add_next_index_zval(zClassDef, zClassname);

   

      /*  loop over classMemberCoun */

@@ -3056,7 +3063,7 @@ static int amf3_unserialize_var(zval **r
      {

       break;

      }

-     ZVAL_ADDREF(zMemberName);

+     Z_ADDREF_P(zMemberName);

      add_next_index_zval(zClassDef,zMemberName);  /*  pass referenc */

     }

 

@@ -3148,6 +3155,7 @@ static int amf3_unserialize_var(zval **r
       return FAILURE;

      }

      MAKE_STD_ZVAL(zValue)

+     zValue->type = 0;

      if(amf3_unserialize_var(&zValue,p,max, var_hash TSRMLS_CC) == FAILURE)

      {

       zval_ptr_dtor(&zValue);

@@ -3180,6 +3188,7 @@ static int amf3_unserialize_var(zval **r
        break;

       }

       MAKE_STD_ZVAL(zValue)

+      zValue->type = 0;

       if(amf3_unserialize_var(&zValue,p,max, var_hash TSRMLS_CC) == FAILURE)

       {

        zval_ptr_dtor(&zValue);

@@ -3201,7 +3210,7 @@ static int amf3_unserialize_var(zval **r
     {

      if(bTypedObject != 0)

      {

-      ZVAL_ADDREF(zClassname);

+      Z_ADDREF_P(zClassname);

       add_assoc_zval(*rval, "_explicitType",zClassname);

      }

     }

@@ -3300,6 +3309,7 @@ static int amf_var_unserialize(zval **rv
     {

      zval * zValue;

      MAKE_STD_ZVAL(zValue);

+     zValue->type = 0;

      if(amf_var_unserialize(&zValue,p,max, var_hash TSRMLS_CC) == FAILURE)

      {

       php_error_docref(NULL TSRMLS_CC, E_NOTICE, "amf bad unserialized value for array index %d",iIndex);

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值