我有一个第三方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)
答案 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,它可以提供有关解释代码的更多有针对性的信息。