使用valgrind调试PHP cli分段错误

时间:2013-12-08 19:44:00

标签: php debugging valgrind

我有一个第三方PHP脚本,我在cli中运行,它正在抛出segmentation fault,我现在正在尝试调试。

刚刚了解了valgrind工具,但我发现的大多数指南似乎都是PHP Apache,而不是cli

如何使用valgrind调试我的cli脚本并弄清楚导致此segmentation fault的原因?

修改

使用@sudowned的帮助,它给了我以下内容,但不确定它告诉我的是什么:

==32363== Invalid read of size 8
==32363==    at 0x6A459A: _zend_mm_alloc_canary_int (in /usr/bin/php5)
==32363==    by 0x6A4CFD: _zend_mm_realloc_canary_int (in /usr/bin/php5)
==32363==    by 0x690CC3: zend_hash_do_resize (in /usr/bin/php5)
==32363==    by 0x6925C7: _zend_hash_add_or_update (in /usr/bin/php5)
==32363==    by 0x68EA1F: add_assoc_zval_ex (in /usr/bin/php5)
==32363==    by 0x69729D: zif_get_defined_constants (in /usr/bin/php5)
==32363==    by 0xE393B63: ??? (in /usr/lib/php5/20090626/suhosin.so)
==32363==    by 0x6D4B15: zend_do_fcall_common_helper_SPEC (in /usr/bin/php5)
==32363==    by 0x6ABD8F: execute (in /usr/bin/php5)
==32363==    by 0xE394115: ??? (in /usr/lib/php5/20090626/suhosin.so)
==32363==    by 0x6D4805: zend_do_fcall_common_helper_SPEC (in /usr/bin/php5)
==32363==    by 0x6ABD8F: execute (in /usr/bin/php5)
==32363==  Address 0x1c486147 is not stack'd, malloc'd or (recently) free'd
==32363== 
==32363== 
==32363== Process terminating with default action of signal 11 (SIGSEGV)
==32363==  Access not within mapped region at address 0x1C486147
==32363==    at 0x6A459A: _zend_mm_alloc_canary_int (in /usr/bin/php5)
==32363==    by 0x6A4CFD: _zend_mm_realloc_canary_int (in /usr/bin/php5)
==32363==    by 0x690CC3: zend_hash_do_resize (in /usr/bin/php5)
==32363==    by 0x6925C7: _zend_hash_add_or_update (in /usr/bin/php5)
==32363==    by 0x68EA1F: add_assoc_zval_ex (in /usr/bin/php5)
==32363==    by 0x69729D: zif_get_defined_constants (in /usr/bin/php5)
==32363==    by 0xE393B63: ??? (in /usr/lib/php5/20090626/suhosin.so)
==32363==    by 0x6D4B15: zend_do_fcall_common_helper_SPEC (in /usr/bin/php5)
==32363==    by 0x6ABD8F: execute (in /usr/bin/php5)
==32363==    by 0xE394115: ??? (in /usr/lib/php5/20090626/suhosin.so)
==32363==    by 0x6D4805: zend_do_fcall_common_helper_SPEC (in /usr/bin/php5)
==32363==    by 0x6ABD8F: execute (in /usr/bin/php5)
==32363==  If you believe this happened as a result of a stack
==32363==  overflow in your program's main thread (unlikely but
==32363==  possible), you can try to increase the size of the
==32363==  main thread stack using the --main-stacksize= flag.
==32363==  The main thread stack size used in this run was 8388608.
==32363== 
==32363== HEAP SUMMARY:
==32363==     in use at exit: 180,903,362 bytes in 27,691 blocks
==32363==   total heap usage: 11,144,829 allocs, 11,117,138 frees, 2,198,841,176 bytes allocated
==32363== 
==32363== LEAK SUMMARY:
==32363==    definitely lost: 0 bytes in 0 blocks
==32363==    indirectly lost: 0 bytes in 0 blocks
==32363==      possibly lost: 0 bytes in 0 blocks
==32363==    still reachable: 180,903,362 bytes in 27,691 blocks
==32363==         suppressed: 0 bytes in 0 blocks
==32363== Reachable blocks (those to which a pointer was found) are not shown.
==32363== To see them, rerun with: --leak-check=full --show-reachable=yes
==32363== 
==32363== For counts of detected and suppressed errors, rerun with: -v
==32363== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 37 from 10)

1 个答案:

答案 0 :(得分:3)

您可以按照Valgrind quick-start guide中的说明,将您的PHP CLI命令链接起来,如下所示:

valgrind --leak-check=yes php -f filename.php args

为了从输出中收集有用信息,您可能需要使用debug symbols.重新编译PHP:

./configure --enable-debug

编辑:为了回应您的评论,请记住,当您使用Valgrind时,您调试您的PHP脚本:您正在调试PHP解释器,这是底层的C可执行文件。

对轻松的人来说,这不是一项任务。

如果没有对C(并进行调试)的深入了解,您将很难从堆栈跟踪中收集有关情况的有用信息。

Valgrind已经准确地告诉你解释器中的函数导致了分段错误。下一步是隔离在段错误时传递给函数的变量。从那里可以深入了解PHP代码如何映射到底层C,然后才能识别PHP指令导致它。

简单的答案是开始评论PHP的行,直到你的段错误不再发生,然后玩有罪行,直到你确定不该做什么。低科技?当然。有效,同样肯定。您还可以使用xdebug,discussed here,它可以提供有关解释代码的更多有针对性的信息。