PhpRiot
News Archive
PhpRiot Newsletter
Your Email Address:

More information

PHP segfaulting with pecl/uuid and pecl/imagick

Note: This article was originally published at Planet PHP on 5 September 2010.
Planet PHP

Ran into a bug yesterday, where http://pecl.php.net/uuid in combination with http://pecl.php.net/imagick yielded a segfault when using uuid_create(). GDB backtrace looks like this (without the exact place where it happens in libuuid, as there is unfortunatly no libuuid1-dbg-package in current Ubuntu versions):

gdb --silent --ex run --args php -r "var_dump(uuid_create());" #0 0xb6e85321 in ?? () from /lib/libuuid.so.1 #1 0xb6e862bf in uuid_generate () from /lib/libuuid.so.1 #2 0xb6bcc67a in zif_uuid_create (ht=0, return_value=0xbffff1e8, return_value_ptr=0x0, this_ptr=0x0, return_value_used=1) at /usr/src/pecl-uuid-trunk/uuid.c:182 #3 0x0835d26a in zend_do_fcall_common_helper_SPEC (execute_data=0x894ed4c) at /build/buildd/php5-5.3.2/Zend/zend_vm_execute.h:313 #4 0x08333d8e in execute (op_array=0x891c464) at /build/buildd/php5-5.3.2/Zend/zend_vm_execute.h:104 #5 0x082fe283 in zend_eval_stringl (str=0xbffff998 "var_dump(uuid_create());", str_len=24, retval_ptr=0x0, string_name=0x871f2fc "Command line code") at /build/buildd/php5-5.3.2/Zend/zend_execute_API.c:1172 #6 0x082fe422 in zend_eval_stringl_ex (str=0xbffff998 "var_dump(uuid_create());", str_len=24, retval_ptr=0x0, string_name=0x871f2fc "Command line code", handle_exceptions=1) at /build/buildd/php5-5.3.2/Zend/zend_execute_API.c:1214 #7 0x082fe4a3 in zend_eval_string_ex (str=0xbffff998 "var_dump(uuid_create());", retval_ptr=0x0, string_name=0x871f2fc "Command line code", handle_exceptions=1) at /build/buildd/php5-5.3.2/Zend/zend_execute_API.c:1225 #8 0x083a0579 in main (argc=3, argv=0xbffff854) at /build/buildd/php5-5.3.2/sapi/cli/php_cli.c:1235

The interesting thing is, the crash happens in libuuid, but only if imagick is enabled. Let's see what Valgrind says:

valgrind -q php -r "var_dump(uuid_create());" ==25103== Invalid write of size 2 ==25103== at 0x5517321: ??? (in /lib/libuuid.so.1.3.0) ==25103== by 0x55182BE: uuid_generate (in /lib/libuuid.so.1.3.0) ==25103== by 0x57D0679: zif_uuid_create (uuid.c:182) ==25103== by 0x835D269: zend_do_fcall_common_helper_SPEC (in /usr/bin/php5) ==25103== by 0x8333D8D: execute (/build/buildd/php5-5.3.2/Zend/zend_vm_execute.h:104) ==25103== by 0x82FE282: zend_eval_stringl (/build/buildd/php5-5.3.2/Zend/zend_execute_API.c:1172) ==25103== by 0x82FE421: zend_eval_stringl_ex (/build/buildd/php5-5.3.2/Zend/zend_execute_API.c:1214) ==25103== by 0x82FE4A2: zend_eval_string_ex (/build/buildd/php5-5.3.2/Zend/zend_execute_API.c:1225) ==25103== by 0x83A0578: main (/build/buildd/php5-5.3.2/sapi/cli/php_cli.c:1235) ==25103== Address 0x30 is not stack'd, malloc'd or (recently) free'd ==25103== ==25103== ==25103== Process terminating with default action of signal 11 (SIGSEGV) ==25103== Access not within mapped region at address 0x30 ==25103== at 0x5517321: ??? (in /lib/libuuid.so.1.3.0) ==25103== by 0x55182BE: uuid_generate (in /lib/libuuid.so.1.3.0) ==25103== by 0x57D0679: zif_uuid_create (uuid.c:182) ==25103== by 0x835D269: zend_do_fcall_common_helper_SPEC (in /usr/bin/php5) ==25103== by 0x8333D8D: execute (/build/buildd/php5-5.3.2/Zend/zend_vm_execute.h:104) ==25103== by 0x82FE282: zend_eval_stringl (/build/buildd/php5-5.3.2/Zend/zend_execute_API.c:1172) ==25103== by 0x82FE421: zend_eval_stringl_ex (/build/buildd/php5-5.3.2/Zend/zend_execute_API.c:1214) ==25103== by 0x82FE4A2: zend_eval_string_ex (/build/buildd/php5-5.3.2/Zend/zend_execute_API.c:1225) ==25103== by 0x83A0578: main (/build/buildd/php5-5.3.2/sapi/cli/php_cli.c:1235) ==25103== If you believe this happened as a result of a stack ==25103== overflow in your program's main thread (unlikely but ==25103== possible), you can try to increase the size of the ==25103== main thread stack using the --main-stacksize= flag. ==25103== The main thread stack size used in this run was 8388608. Segmentation fault

Not really any more helpful. After two hours debugging the issue with the help of Mikko and Pierre we found out, that pecl/imagick is linked against libuuid too:

ldd /usr/lib/php5/20090626+lfs/imagick.so (...) libuuid.so.1 = /lib/libuuid.so.1 (0xb7086000) (...)

For whatever reason this is happening, this is most likely the root cause of the issue.

Solution (sort of)

pecl/uuid was loaded by /etc/php5/conf.d/uuid.ini and pecl/imagick by /etc/php5/conf.d/imagick.ini. As they are loaded in there alphabetical order, imagick initialized before uuid. Renaming /etc/php5/conf.d/uuid.ini to /etc/php5/conf.d/00-uuid.ini fixed the issue, as uuid is than initialized before imagick and the segmentation fault was gone.

Not sure about that, but maybe it would be a good idea to check in PHP_MINIT(uuid) in pecl/uuid if pecl/imagick has been initialized before and warn the user about it?