So I wanted a blogpost about code discovery. And then I got so excited I wanted to use XHProf and then my said 'oh hell no'. Here you are the story.
XHProf is hosted by PECL. But
sudo pecl install xhprof
doesn't do anything because it's a beta version. All right let's use the proper channel
sudo pecl install channel://pecl.php.net/xhprof-0.9.2
Nah, it fails too. All righty then, let's go dirty and compile it. Google is very kind to offer you many tutorials - which all failed to me. One of the best is from Lullabot. But - this too - provided me the same error. I downloaded the PHP source with the same version (5.4.10 is the closest available to 5.4.4 - it's ok), got XHProf version 0.9.2, run
phpize make
And it gave me this:
/bin/sh /private/tmp/pear/temp/pear-build-rootGjn44l/xhprof-0.9.2/libtool --mode=compile cc -I. -I/private/tmp/pear/temp/xhprof/extension -DPHP_ATOM_INC -I/private/tmp/pear/temp/pear-build-rootGjn44l/xhprof-0.9.2/include -I/private/tmp/pear/temp/pear-build-rootGjn44l/xhprof-0.9.2/main -I/private/tmp/pear/temp/xhprof/extension -I/Applications/MAMP/bin/php/php5.4.4/include/php -I/Applications/MAMP/bin/php/php5.4.4/include/php/main -I/Applications/MAMP/bin/php/php5.4.4/include/php/TSRM -I/Applications/MAMP/bin/php/php5.4.4/include/php/Zend -I/Applications/MAMP/bin/php/php5.4.4/include/php/ext -I/Applications/MAMP/bin/php/php5.4.4/include/php/ext/date/lib -DHAVE_CONFIG_H -g -O2 -c /private/tmp/pear/temp/xhprof/extension/xhprof.c -o xhprof.lo mkdir .libs cc -I. -I/private/tmp/pear/temp/xhprof/extension -DPHP_ATOM_INC -I/private/tmp/pear/temp/pear-build-rootGjn44l/xhprof-0.9.2/include -I/private/tmp/pear/temp/pear-build-rootGjn44l/xhprof-0.9.2/main -I/private/tmp/pear/temp/xhprof/extension -I/Applications/MAMP/bin/php/php5.4.4/include/php -I/Applications/MAMP/bin/php/php5.4.4/include/php/main -I/Applications/MAMP/bin/php/php5.4.4/include/php/TSRM -I/Applications/MAMP/bin/php/php5.4.4/include/php/Zend -I/Applications/MAMP/bin/php/php5.4.4/include/php/ext -I/Applications/MAMP/bin/php/php5.4.4/include/php/ext/date/lib -DHAVE_CONFIG_H -g -O2 -c /private/tmp/pear/temp/xhprof/extension/xhprof.c -fno-common -DPIC -o .libs/xhprof.o /private/tmp/pear/temp/xhprof/extension/xhprof.c:635:5: warning: implicit declaration of function 'restore_cpu_affinity' is invalid in C99 [-Wimplicit-function-declaration] restore_cpu_affinity(&hp_globals.prev_mask); ^ /private/tmp/pear/temp/xhprof/extension/xhprof.c:639:3: warning: implicit declaration of function 'bind_to_cpu' is invalid in C99 [-Wimplicit-function-declaration] bind_to_cpu((int) (rand() % hp_globals.cpu_num)); ^ /private/tmp/pear/temp/xhprof/extension/xhprof.c:898:10: warning: assigning to 'char *' from 'const char *' discards qualifiers [-Wincompatible-pointer-types] func = curr_func->common.function_name; ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /private/tmp/pear/temp/xhprof/extension/xhprof.c:909:13: warning: assigning to 'char *' from 'const char *' discards qualifiers [-Wincompatible-pointer-types] cls = curr_func->common.scope->name; ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /private/tmp/pear/temp/xhprof/extension/xhprof.c:911:13: warning: assigning to 'char *' from 'const char *' discards qualifiers [-Wincompatible-pointer-types] cls = Z_OBJCE(*data->object)->name; ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /private/tmp/pear/temp/xhprof/extension/xhprof.c:930:35: error: no member named 'u' in 'union _znode_op' curr_op = data->opline->op2.u.constant.value.lval; ~~~~~~~~~~~~~~~~~ ^ /private/tmp/pear/temp/xhprof/extension/xhprof.c:963:41: warning: passing 'const char *' to parameter of type 'char *' discards qualifiers [-Wincompatible-pointer-types] filename = hp_get_base_filename((curr_func->op_array).filename); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /private/tmp/pear/temp/xhprof/extension/xhprof.c:856:41: note: passing argument to parameter 'filename' here static char *hp_get_base_filename(char *filename) { ^ /private/tmp/pear/temp/xhprof/extension/xhprof.c:1206:7: warning: implicit declaration of function 'thread_policy_set' is invalid in C99 [-Wimplicit-function-declaration] if (SET_AFFINITY(0, sizeof(cpu_set_t), &new_mask) < 0) { ^ /private/tmp/pear/temp/xhprof/extension/xhprof.c:60:9: note: expanded from macro 'SET_AFFINITY' thread_policy_set(mach_thread_self(), THREAD_AFFINITY_POLICY, mask, \ ^ /private/tmp/pear/temp/xhprof/extension/xhprof.c:1650:44: error: no member named 'u' in 'union _znode_op' EX_T(opline->result.u.var).var.ptr, ~~~~~~~~~~~~~~~~~~~~^~~~~~ /private/tmp/pear/temp/xhprof/extension/xhprof.c:1624:60: note: expanded from macro 'EX_T' #define EX_T(offset) (*(temp_variable *)((char *) EX(Ts) + offset)) ^ /private/tmp/pear/temp/xhprof/extension/xhprof.c:1683:35: warning: passing 'const char *' to parameter of type 'char *' discards qualifiers [-Wincompatible-pointer-types] filename = hp_get_base_filename(file_handle->filename); ^~~~~~~~~~~~~~~~~~~~~ /private/tmp/pear/temp/xhprof/extension/xhprof.c:856:41: note: passing argument to parameter 'filename' here static char *hp_get_base_filename(char *filename) { ^ 8 warnings and 2 errors generated. make: *** [xhprof.lo] Error 1 ERROR: `make' failed
Don't panic. (I did, btw.) So what do you do? Blame GCC? Blame the environment? Blame Apple? I was looking for the error messages - here and there I've found some ideas but nothing particular. They said it's not gonna work with PHP 5.4.4. I was thinking in alternatives, such as Brew or an already compiled version. But you know well you're hurt already.
So I was wondering how could I set GCC to co-op with XHProf. I was looking for compile arguments and edited the Makefile - and how funny it worked :D Well, I set a stage preprocessor that went through 'make' just fine - but of course it was a preprocessor. Anyways - no help there neither.
Then I realized I always miss something. The error message. If you look at the problem you can actually see the problem:
/private/tmp/pear/temp/xhprof/extension/xhprof.c:930:35: error: no member named 'u' in 'union _znode_op' curr_op = data->opline->op2.u.constant.value.lval;
Then a more targeted search and found it: http://lists.freebsd.org/pipermail/freebsd-ports-bugs/2012-May/234478.html the patch! Actually you need to change only two things. From this:
curr_op = data->opline->extended_value;
to this:
curr_op = data->opline->op2.u.constant.value.lval;
And from this:
temp_variable *retvar = &EX_T(opline->result.var); ((zend_internal_function *) EX(function_state).function)->handler( opline->extended_value, retvar->var.ptr, (EX(function_state).function->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) ? &retvar->var.ptr:NULL, EX(object), ret TSRMLS_CC);
to this:
((zend_internal_function *) EX(function_state).function)->handler( opline->extended_value, EX_T(opline->result.u.var).var.ptr, EX(function_state).function->common.return_reference ? &EX_T(opline->result.u.var).var.ptr:NULL, EX(object), ret TSRMLS_CC);
Then you have to force remake:
make -B
And fuck yeah:
If you found this via esoteric Google searches like me, there's an easier way to do this. xhprof was patched to work fine with php5.4, but that code has not made it into PECL yet.
ReplyDeleteInstead of patching xhprof.c, try this:
git checkout https://github.com/facebook/xhprof
cd xhprof/extension
phpize
./configure
make
make install
Works :)
Hi there, thank you very much. I'll keep it mind. I was hoping they manage to have a new release with a fix - but if it's already there in the FB repo it's the same good. Thank you very much for pointing that out :)
ReplyDelete