Я постоянно получаю zend_mm_heap_corrupted ошибки в моем приложении — особенно от работников gearman, которые интенсивно используют phpredis, поэтому я подозреваю причину повреждения памяти в одном из этих расширений php.
Когда я отключаю менеджер памяти Zend, используя export USE_ZEND_ALLOC=0
Я получаю гораздо больше сообщений об ошибках от glibc:
*** glibc detected *** php: double free or corruption (!prev): 0x00000000035f61c0 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x75be6)[0x7f6805348be6]
/lib/x86_64-linux-gnu/libc.so.6(cfree+0x6c)[0x7f680534d98c]
php[0x7c3f14]
php(execute_ex+0x38)[0x7aaa18]
php(dtrace_execute_ex+0x7d)[0x73059d]
php[0x7e5ed8]
php(execute_ex+0x38)[0x7aaa18]
php(dtrace_execute_ex+0x7d)[0x73059d]
php(zend_call_function+0xae6)[0x7322d6]
php(zif_call_user_func_array+0x5f)[0x66034f]
php(dtrace_execute_internal+0x39)[0x7306c9]
php[0x7e58a1]
php(execute_ex+0x38)[0x7aaa18]
php(dtrace_execute_ex+0x7d)[0x73059d]
php(zend_call_function+0xae6)[0x7322d6]
/usr/lib/php5/20131226/gearman.so(+0xd735)[0x7f68007cf735]
/usr/lib/x86_64-linux-gnu/libgearman.so.8(+0xebbc)[0x7f68005a7bbc]
/usr/lib/x86_64-linux-gnu/libgearman.so.8(gearman_worker_work+0x15c)[0x7f68005b0dec]
/usr/lib/php5/20131226/gearman.so(zif_gearman_worker_work+0x58)[0x7f68007cf2c8]
php(dtrace_execute_internal+0x39)[0x7306c9]
php[0x7e58a1]
php(execute_ex+0x38)[0x7aaa18]
php(dtrace_execute_ex+0x7d)[0x73059d]
php[0x7e5ed8]
php(execute_ex+0x38)[0x7aaa18]
php(dtrace_execute_ex+0x7d)[0x73059d]
php[0x7e5ed8]
php(execute_ex+0x38)[0x7aaa18]
php(dtrace_execute_ex+0x7d)[0x73059d]
php[0x7e5ed8]
php(execute_ex+0x38)[0x7aaa18]
php(dtrace_execute_ex+0x7d)[0x73059d]
php[0x7e5ed8]
php(execute_ex+0x38)[0x7aaa18]
php(dtrace_execute_ex+0x7d)[0x73059d]
php(zend_call_function+0xae6)[0x7322d6]
php(zif_call_user_func_array+0x5f)[0x66034f]
php(dtrace_execute_internal+0x39)[0x7306c9]
php[0x7e58a1]
php(execute_ex+0x38)[0x7aaa18]
php(dtrace_execute_ex+0x7d)[0x73059d]
php[0x7e5ed8]
php(execute_ex+0x38)[0x7aaa18]
php(dtrace_execute_ex+0x7d)[0x73059d]
php[0x7e5ed8]
php(execute_ex+0x38)[0x7aaa18]
php(dtrace_execute_ex+0x7d)[0x73059d]
php[0x7e5ed8]
php(execute_ex+0x38)[0x7aaa18]
php(dtrace_execute_ex+0x7d)[0x73059d]
php[0x7e5ed8]
php(execute_ex+0x38)[0x7aaa18]
php(dtrace_execute_ex+0x7d)[0x73059d]
php[0x7e5ed8]
php(execute_ex+0x38)[0x7aaa18]
php(dtrace_execute_ex+0x7d)[0x73059d]
php[0x7e5ed8]
php(execute_ex+0x38)[0x7aaa18]
php(dtrace_execute_ex+0x7d)[0x73059d]
php(zend_execute_scripts+0x158)[0x742ef8]
php(php_execute_script+0x292)[0x6de592]
php[0x7e8e34]
php(main+0x50f)[0x472c1f]
Как мне получить то место, где был выделен и освобожден блок памяти?
Я пытался использовать USE_ZEND_ALLOC=0 valgrind --track-origins=yes --trace-children=yes --leak-check=no /usr/local/bin/gearmanctl restart myworker
но я понятия не имею, как получить происхождение рассматриваемых блоков памяти:
==24013== Invalid read of size 4
==24013== at 0x7462DC: ZEND_FE_FETCH_SPEC_VAR_HANDLER (in /usr/bin/php5)
==24013== by 0x762447: execute_ex (in /usr/bin/php5)
==24013== by 0x6E7F6C: dtrace_execute_ex (in /usr/bin/php5)
==24013== by 0x79D927: zend_do_fcall_common_helper_SPEC (in /usr/bin/php5)
==24013== by 0x762447: execute_ex (in /usr/bin/php5)
==24013== by 0x6E7F6C: dtrace_execute_ex (in /usr/bin/php5)
==24013== by 0x6E9CA5: zend_call_function (in /usr/bin/php5)
==24013== by 0x617D1E: zif_call_user_func_array (in /usr/bin/php5)
==24013== by 0x6E8098: dtrace_execute_internal (in /usr/bin/php5)
==24013== by 0x79D2F0: zend_do_fcall_common_helper_SPEC (in /usr/bin/php5)
==24013== by 0x762447: execute_ex (in /usr/bin/php5)
==24013== by 0x6E7F6C: dtrace_execute_ex (in /usr/bin/php5)
==24013== Address 0x134c5ff0 is 16 bytes inside a block of size 32 free'd
==24013== at 0x4C27D4E: free (vg_replace_malloc.c:427)
==24013== by 0x718868: gc_collect_cycles (in /usr/bin/php5)
==24013== by 0x718CA2: gc_zobj_possible_root (in /usr/bin/php5)
==24013== by 0x775C47: zend_assign_to_object (in /usr/bin/php5)
==24013== by 0x776663: ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_HANDLER (in /usr/bin/php5)
==24013== by 0x762447: execute_ex (in /usr/bin/php5)
==24013== by 0x6E7F6C: dtrace_execute_ex (in /usr/bin/php5)
==24013== by 0x79D927: zend_do_fcall_common_helper_SPEC (in /usr/bin/php5)
==24013== by 0x762447: execute_ex (in /usr/bin/php5)
==24013== by 0x6E7F6C: dtrace_execute_ex (in /usr/bin/php5)
==24013== by 0x79D927: zend_do_fcall_common_helper_SPEC (in /usr/bin/php5)
==24013== by 0x762447: execute_ex (in /usr/bin/php5)
==24013==
Я также пытался урезать код до небольшого образца, но не смог воспроизвести ошибку.
Задача ещё не решена.
Других решений пока нет …