@@ -313,24 +313,30 @@ static int opencensus_trace_call_user_function_callback(zend_execute_data *execu
313313 int i , num_args = EX_NUM_ARGS (), has_scope = 0 ;
314314 zval * args = emalloc ((num_args + 1 ) * sizeof (zval ));
315315
316- if (getThis () == NULL ) {
317- ZVAL_NULL (& args [0 ]);
318- } else {
316+ if (getThis () != NULL ) {
319317 has_scope = 1 ;
320- ZVAL_ZVAL (& args [0 ], getThis (), 0 , 1 );
318+ ZVAL_COPY (& args [0 ], getThis ());
321319 }
322320
323321 for (i = 0 ; i < num_args ; i ++ ) {
324- ZVAL_ZVAL (& args [i + has_scope ], EX_VAR_NUM (i ), 0 , 1 );
322+ ZVAL_COPY (& args [i + has_scope ], EX_VAR_NUM (i ));
325323 }
326324
327325 if (call_user_function_ex (EG (function_table ), NULL , callback , callback_result , num_args + has_scope , args , 0 , NULL ) != SUCCESS ) {
326+ for (i = 0 ; i < num_args + has_scope ; i ++ ) {
327+ ZVAL_DESTRUCTOR (& args [i ]);
328+ }
328329 efree (args );
329330 return FAILURE ;
330331 }
332+ for (i = 0 ; i < num_args + has_scope ; i ++ ) {
333+ ZVAL_DESTRUCTOR (& args [i ]);
334+ }
331335 efree (args );
332336
333337 if (EG (exception ) != NULL ) {
338+ php_error_docref (NULL , E_WARNING , "Exception in trace callback" );
339+ zend_clear_exception ();
334340 return FAILURE ;
335341 }
336342
@@ -353,16 +359,18 @@ static int opencensus_trace_call_user_function_callback(zend_execute_data *execu
353359 */
354360static void opencensus_trace_execute_callback (opencensus_trace_span_t * span , zend_execute_data * execute_data , zval * span_options TSRMLS_DC )
355361{
356- zend_string * callback_name ;
362+ zend_string * callback_name = NULL ;
357363 if (zend_is_callable (span_options , 0 , & callback_name )) {
358364 zval callback_result ;
359365 if (opencensus_trace_call_user_function_callback (execute_data , span , span_options , & callback_result TSRMLS_CC ) == SUCCESS ) {
360366 opencensus_trace_span_apply_span_options (span , & callback_result );
361367 }
368+ ZVAL_DESTRUCTOR (& callback_result );
362369 zend_string_release (callback_name );
363370 } else if (Z_TYPE_P (span_options ) == IS_ARRAY ) {
364371 opencensus_trace_span_apply_span_options (span , span_options );
365372 }
373+ zend_string_release (callback_name );
366374}
367375
368376/**
@@ -388,14 +396,14 @@ static zend_string *generate_span_id()
388396 * Start a new trace span. Inherit the parent span id from the current trace
389397 * context
390398 */
391- static opencensus_trace_span_t * opencensus_trace_begin (zend_string * function_name , zend_execute_data * execute_data , zend_string * span_id TSRMLS_DC )
399+ static opencensus_trace_span_t * opencensus_trace_begin (zend_string * name , zend_execute_data * execute_data , zend_string * span_id TSRMLS_DC )
392400{
393401 opencensus_trace_span_t * span = opencensus_trace_span_alloc ();
394402
395403 zend_fetch_debug_backtrace (& span -> stackTrace , 1 , DEBUG_BACKTRACE_IGNORE_ARGS , 0 );
396404
397405 span -> start = opencensus_now ();
398- span -> name = zend_string_copy (function_name );
406+ span -> name = zend_string_copy (name );
399407 if (span_id ) {
400408 span -> span_id = zend_string_copy (span_id );
401409 } else {
@@ -407,12 +415,9 @@ static opencensus_trace_span_t *opencensus_trace_begin(zend_string *function_nam
407415 }
408416
409417 OPENCENSUS_TRACE_G (current_span ) = span ;
410- zval ptr ;
411- ZVAL_PTR (& ptr , span );
412418
413419 /* add the span to the list of spans */
414- // printf("inserting span with span id: %s\n", ZSTR_VAL(span->span_id));
415- zend_hash_add (OPENCENSUS_TRACE_G (spans ), span -> span_id , & ptr );
420+ zend_hash_add_ptr (OPENCENSUS_TRACE_G (spans ), span -> span_id , span );
416421
417422 return span ;
418423}
@@ -488,12 +493,15 @@ PHP_FUNCTION(opencensus_trace_begin)
488493
489494 if (span_options == NULL ) {
490495 array_init (& default_span_options );
491- span_options = & default_span_options ;
496+ span = opencensus_trace_begin (function_name , execute_data , NULL TSRMLS_CC );
497+ opencensus_trace_execute_callback (span , execute_data , & default_span_options TSRMLS_CC );
498+ ZVAL_DESTRUCTOR (& default_span_options );
499+ } else {
500+ span_id = span_id_from_options (Z_ARR_P (span_options ));
501+ span = opencensus_trace_begin (function_name , execute_data , span_id TSRMLS_CC );
502+ opencensus_trace_execute_callback (span , execute_data , span_options TSRMLS_CC );
492503 }
493504
494- span_id = span_id_from_options (Z_ARR_P (span_options ));
495- span = opencensus_trace_begin (function_name , execute_data , span_id TSRMLS_CC );
496- opencensus_trace_execute_callback (span , execute_data , span_options TSRMLS_CC );
497505 RETURN_TRUE ;
498506}
499507
@@ -510,31 +518,39 @@ PHP_FUNCTION(opencensus_trace_finish)
510518 RETURN_FALSE ;
511519}
512520
521+ static void span_dtor (zval * zv )
522+ {
523+ opencensus_trace_span_t * span = Z_PTR_P (zv );
524+ opencensus_trace_span_free (span );
525+ ZVAL_PTR_DTOR (zv );
526+ }
527+
513528/**
514529 * Reset the list of spans and free any allocated memory used.
515530 * If reset is set, reallocate request globals so we can start capturing spans.
516531 */
517532static void opencensus_trace_clear (int reset TSRMLS_DC )
518533{
519- opencensus_trace_span_t * span ;
520-
521- /* free memory for all captured spans */
522- ZEND_HASH_FOREACH_PTR (OPENCENSUS_TRACE_G (spans ), span ) {
523- opencensus_trace_span_free (span );
524- } ZEND_HASH_FOREACH_END ();
525-
526534 /* free the hashtable */
535+ zend_hash_destroy (OPENCENSUS_TRACE_G (spans ));
527536 FREE_HASHTABLE (OPENCENSUS_TRACE_G (spans ));
528537
529538 /* reallocate and setup the hashtable for captured spans */
530539 if (reset ) {
531540 ALLOC_HASHTABLE (OPENCENSUS_TRACE_G (spans ));
532- zend_hash_init (OPENCENSUS_TRACE_G (spans ), 16 , NULL , ZVAL_PTR_DTOR , 0 );
541+ zend_hash_init (OPENCENSUS_TRACE_G (spans ), 16 , NULL , span_dtor , 0 );
533542 }
534543
535544 OPENCENSUS_TRACE_G (current_span ) = NULL ;
536- OPENCENSUS_TRACE_G (trace_id ) = NULL ;
537- OPENCENSUS_TRACE_G (trace_parent_span_id ) = 0 ;
545+ if (OPENCENSUS_TRACE_G (trace_id )) {
546+ zend_string_release (OPENCENSUS_TRACE_G (trace_id ));
547+ OPENCENSUS_TRACE_G (trace_id ) = NULL ;
548+ }
549+
550+ if (OPENCENSUS_TRACE_G (trace_parent_span_id )) {
551+ zend_string_release (OPENCENSUS_TRACE_G (trace_parent_span_id ));
552+ OPENCENSUS_TRACE_G (trace_parent_span_id ) = NULL ;
553+ }
538554}
539555
540556/**
@@ -556,13 +572,15 @@ PHP_FUNCTION(opencensus_trace_clear)
556572 */
557573PHP_FUNCTION (opencensus_trace_set_context )
558574{
559- zend_string * trace_id , * parent_span_id ;
575+ zend_string * trace_id = NULL , * parent_span_id = NULL ;
560576 if (zend_parse_parameters (ZEND_NUM_ARGS () TSRMLS_CC , "S|S" , & trace_id , & parent_span_id ) == FAILURE ) {
561577 RETURN_FALSE ;
562578 }
563579
564580 OPENCENSUS_TRACE_G (trace_id ) = zend_string_copy (trace_id );
565- OPENCENSUS_TRACE_G (trace_parent_span_id ) = zend_string_copy (parent_span_id );
581+ if (parent_span_id ) {
582+ OPENCENSUS_TRACE_G (trace_parent_span_id ) = zend_string_copy (parent_span_id );
583+ }
566584
567585 RETURN_TRUE ;
568586}
@@ -654,7 +672,7 @@ void opencensus_trace_execute_internal(INTERNAL_FUNCTION_PARAMETERS)
654672 } else {
655673 resume_execute_internal (INTERNAL_FUNCTION_PARAM_PASSTHRU );
656674 }
657- /* zend_string_release(function_name); */
675+ zend_string_release (function_name );
658676 } else {
659677 resume_execute_internal (INTERNAL_FUNCTION_PARAM_PASSTHRU );
660678 }
@@ -670,7 +688,7 @@ void opencensus_trace_execute_internal(INTERNAL_FUNCTION_PARAMETERS)
670688PHP_FUNCTION (opencensus_trace_function )
671689{
672690 zend_string * function_name ;
673- zval * handler = NULL , * copy ;
691+ zval * handler = NULL ;
674692 zval h ;
675693
676694 if (zend_parse_parameters (ZEND_NUM_ARGS () TSRMLS_CC , "S|z" , & function_name , & handler ) == FAILURE ) {
@@ -680,13 +698,11 @@ PHP_FUNCTION(opencensus_trace_function)
680698 if (handler == NULL ) {
681699 ZVAL_LONG (& h , 1 );
682700 handler = & h ;
701+ } else {
702+ ZVAL_COPY (& h , handler );
683703 }
684704
685- /* Note: these is freed in the RSHUTDOWN via opencensus_trace_clear */
686- PHP_OPENCENSUS_MAKE_STD_ZVAL (copy );
687- ZVAL_ZVAL (copy , handler , 1 , 0 );
688-
689- zend_hash_update (OPENCENSUS_TRACE_G (user_traced_functions ), function_name , copy );
705+ zend_hash_update (OPENCENSUS_TRACE_G (user_traced_functions ), function_name , & h );
690706 RETURN_TRUE ;
691707}
692708
@@ -701,7 +717,7 @@ PHP_FUNCTION(opencensus_trace_function)
701717PHP_FUNCTION (opencensus_trace_method )
702718{
703719 zend_string * class_name , * function_name , * key ;
704- zval * handler = NULL , * copy ;
720+ zval * handler = NULL ;
705721 zval h ;
706722
707723 if (zend_parse_parameters (ZEND_NUM_ARGS () TSRMLS_CC , "SS|z" , & class_name , & function_name , & handler ) == FAILURE ) {
@@ -711,14 +727,13 @@ PHP_FUNCTION(opencensus_trace_method)
711727 if (handler == NULL ) {
712728 ZVAL_LONG (& h , 1 );
713729 handler = & h ;
730+ } else {
731+ ZVAL_COPY (& h , handler );
714732 }
715733
716- /* Note: these is freed in the RSHUTDOWN via opencensus_trace_clear */
717- PHP_OPENCENSUS_MAKE_STD_ZVAL (copy );
718- ZVAL_ZVAL (copy , handler , 1 , 0 );
719-
720734 key = opencensus_trace_generate_class_name (class_name , function_name );
721- zend_hash_update (OPENCENSUS_TRACE_G (user_traced_functions ), key , handler );
735+ zend_hash_update (OPENCENSUS_TRACE_G (user_traced_functions ), key , & h );
736+ zend_string_release (key );
722737
723738 RETURN_FALSE ;
724739}
@@ -732,11 +747,11 @@ PHP_FUNCTION(opencensus_trace_method)
732747PHP_FUNCTION (opencensus_trace_list )
733748{
734749 opencensus_trace_span_t * trace_span ;
735- zval span ;
736750
737751 array_init (return_value );
738752
739753 ZEND_HASH_FOREACH_PTR (OPENCENSUS_TRACE_G (spans ), trace_span ) {
754+ zval span ;
740755 opencensus_trace_span_to_zval (trace_span , & span );
741756 add_next_index_zval (return_value , & span TSRMLS_CC );
742757 } ZEND_HASH_FOREACH_END ();
@@ -801,11 +816,11 @@ PHP_RINIT_FUNCTION(opencensus)
801816
802817 /* initialize storage for recorded spans - per request basis */
803818 ALLOC_HASHTABLE (OPENCENSUS_TRACE_G (spans ));
804- zend_hash_init (OPENCENSUS_TRACE_G (spans ), 16 , NULL , ZVAL_PTR_DTOR , 0 );
819+ zend_hash_init (OPENCENSUS_TRACE_G (spans ), 16 , NULL , span_dtor , 0 );
805820
806821 OPENCENSUS_TRACE_G (current_span ) = NULL ;
807822 OPENCENSUS_TRACE_G (trace_id ) = NULL ;
808- OPENCENSUS_TRACE_G (trace_parent_span_id ) = 0 ;
823+ OPENCENSUS_TRACE_G (trace_parent_span_id ) = NULL ;
809824
810825 return SUCCESS ;
811826}
@@ -814,14 +829,10 @@ PHP_RINIT_FUNCTION(opencensus)
814829 */
815830PHP_RSHUTDOWN_FUNCTION (opencensus )
816831{
817- zval * handler ;
818-
819832 opencensus_trace_clear (0 TSRMLS_CC );
820833
821834 /* cleanup user_traced_functions zvals that we copied when registing */
822- ZEND_HASH_FOREACH_VAL (OPENCENSUS_TRACE_G (user_traced_functions ), handler ) {
823- PHP_OPENCENSUS_FREE_STD_ZVAL (handler );
824- } ZEND_HASH_FOREACH_END ();
835+ zend_hash_destroy (OPENCENSUS_TRACE_G (user_traced_functions ));
825836 FREE_HASHTABLE (OPENCENSUS_TRACE_G (user_traced_functions ));
826837
827838 return SUCCESS ;
0 commit comments