phacility / xhprof

XHProf is a function-level hierarchical profiler for PHP and has a simple HTML based user interface.
http://pecl.php.net/package/xhprof
Apache License 2.0
2.6k stars 925 forks source link

when array_pop be called, phpfpm core dump #63

Open domyway opened 9 years ago

domyway commented 9 years ago

PHP 5.6.4 (cli) (built: Jan 22 2015 18:32:17) Linux slave-6 2.6.32-431.el6.x86_64 #1 SMP Fri Nov 22 03:15:09 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux

index.php: xhprof_enable();

$test = array('test', 'test2');

array_pop($test);

$xhprof_data = xhprof_disable();

php index.php Segmentation fault (core dumped)

And I gdb the /tmp/coredumpfile

(gdb) bt

0 0x00000000006e0690 in zif_array_walk (ht=34685360, return_value=0x0, return_value_ptr=, this_ptr=,

return_value_used=<value optimized out>) at /home/www/Downloads/php-5.6.4/ext/standard/array.c:1131

1 0x00007fa6042370f0 in ?? ()

2 0x00000000012a8620 in fp_maskr ()

3 0x000000000087340d in zend_do_fcall_common_helper_SPEC (execute_data=) at /home/www/Downloads/php-5.6.4/Zend/zend_vm_execute.h:629

4 0x0000000000862fa0 in ZEND_INCLUDE_OR_EVAL_SPEC_CONST_HANDLER (execute_data=0x0) at /home/www/Downloads/php-5.6.4/Zend/zend_vm_execute.h:3016

5 0x00000000012a8798 in fp_maskr ()

6 0x0000000000000000 in ?? ()

is this a xhprof bug? how to fixed this bug?

yaoguais commented 9 years ago

When I clone this version that base on day of 2015-05-04, I get core dump too. Then I found the code in php is changed but xhprof was not followed.

In php 5.6.8.


ZEND_API void execute_internal(zend_execute_data *execute_data_ptr, zend_fcall_info *fci, int return_value_used TSRMLS_DC)
{
    if (fci != NULL) {
        execute_data_ptr->function_state.function->internal_function.handler(
            fci->param_count, *fci->retval_ptr_ptr, fci->retval_ptr_ptr,
            fci->object_ptr, 1 TSRMLS_CC
        );
    } else {
        zval **return_value_ptr = &EX_TMP_VAR(execute_data_ptr, execute_data_ptr->opline->result.var)->var.ptr;
        execute_data_ptr->function_state.function->internal_function.handler(
            execute_data_ptr->opline->extended_value + execute_data_ptr->call->num_additional_args,
            *return_value_ptr, return_value_ptr,
            execute_data_ptr->object, return_value_used TSRMLS_CC
        );
    }
}

I changed the code to execute_internal,and I got the correct result.

the code:


#if ZEND_EXTENSION_API_NO >= 220121212
    /* PHP 5.5. This is just inlining a copy of execute_internal(). */

    if (fci != NULL) {
      ((zend_internal_function *) execute_data->function_state.function)->handler(
        fci->param_count,
        *fci->retval_ptr_ptr,
        fci->retval_ptr_ptr,
        fci->object_ptr,
        1 TSRMLS_CC);
    } else {
      zval **return_value_ptr = &EX_TMP_VAR(current_data, current_data->opline->result.var)->var.ptr;
      current_data->function_state.function->internal_function.handler(
              current_data->opline->extended_value + current_data->call->num_additional_args,
            *return_value_ptr, return_value_ptr,
            current_data->object, ret TSRMLS_CC
        );
    }
#elif ZEND_EXTENSION_API_NO >= 220100525

the old code is:


#if ZEND_EXTENSION_API_NO >= 220121212
    /* PHP 5.5. This is just inlining a copy of execute_internal(). */

    if (fci != NULL) {
      ((zend_internal_function *) execute_data->function_state.function)->handler(
        fci->param_count,
        *fci->retval_ptr_ptr,
        fci->retval_ptr_ptr,
        fci->object_ptr,
        1 TSRMLS_CC);
    } else {
      zval **return_value_ptr = &EX_TMP_VAR(execute_data, execute_data->opline->result.var)->var.ptr;
      ((zend_internal_function *) execute_data->function_state.function)->handler(
        execute_data->opline->extended_value,
        *return_value_ptr,
        (execute_data->function_state.function->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
          ? return_value_ptr
          : NULL,
        execute_data->object,
        ret TSRMLS_CC);
    }
#elif ZEND_EXTENSION_API_NO >= 220100525

I think you may ignored this change.

index.php


<?php

xhprof_enable();

$test = array('test', 'test2');

array_pop($test);

$xhprof_data = xhprof_disable();

print_r($xhprof_data);

result:


root@yaoguai-Hi-Fi-Z87W:~/download/php-5.6.8/ext/xhprof/extension# /root/php568d/bin/php /root/php568d/xhprof/index.php
Array
(
    [main()==>array_pop] => Array
        (
            [ct] => 1
            [wt] => 33
        )

    [main()==>xhprof_disable] => Array
        (
            [ct] => 1
            [wt] => 1
        )

    [main()] => Array
        (
            [ct] => 1
            [wt] => 132
        )

)
beberlei commented 9 years ago

We have a maintained fork of Xhprof that provides support for PHP 5.6. It also adds performance improvements and other cleanups. You can either install it from https://github.com/tideways/php-profiler-extension or use the package repositories/downloads here https://tideways.io/profiler/downloads