使用 gdb 調試 PHP 擴展

來自:http://www.codefrom.com/paper/%E4%BD%BF%E7%94%A8gdb%E8%B0%83%E8%AF%95p...php

php的擴展使用c/c++開發,能夠很容易的使用gdb進行調試。具體步驟以下:
首先編譯php的時候須要加上** --enable-debug**參數c++

./configure --enable-debug
make && make install

在個人ubuntu機器上面測試,擴展的目錄默認爲 /usr/local/lib/php/extensions/debug-non-zts-20131226/
這樣進行php的源碼調試也很方便。
下一步進行擴展建立,進入php源碼的ext目錄,運行ubuntu

./ext_skel --extname=mydebug

當前目錄下會自動生成mydebug目錄,而後進入該目錄,編輯config.m4文件,去掉10~12行的dnl,以下函數

PHP_ARG_WITH(mydebug, for mydebug support,
Make sure that the comment is aligned:
[  --with-mydebug             Include mydebug support])

在最後一行添加測試

if test -z "$PHP_DEBUG"; then
        AC_ARG_ENABLE(debug,
                [--enable-debg  compile with debugging system],
                [PHP_DEBUG=$enableval], [PHP_DEBUG=no]
        )
fi

這樣就表示該擴展可以進行調試了,而後編譯該擴展,使用命令this

phpize 
./configure --enable-debug
make && make install

這裏的 phpizephp-config 須要事先配置好環境變量,而後加載該擴展。在個人機器上面地址爲 /usr/local/lib/php/extensions/debug-non-zts-20131226/。進入mydebug擴展源碼目錄,默認生成的函數爲 confirm_mydebug_compiled,定義在 mydebug.c,擴展自動生成的函數。debug

PHP_FUNCTION(confirm_mydebug_compiled)
{
        char *arg = NULL;
        int arg_len, len;
        char *strg;

        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &arg, &arg_len) == FAILURE) {
                return;
        }

        len = spprintf(&strg, 0, "Congratulations! You have successfully modified ext/%.78s/config.m4. Module %.78s is now compiled into PHP.", "mydebug", arg);
        RETURN_STRINGL(strg, len, 0);
}

大概意思就是獲取字符串參數,而後拼成一句字符串返回。經過nm命令查看生成的mydebug.so導出的符號。調試

運行 nm mydebug.so
返回 zif_confirm_mydebug_compiled
    ……

PHP_FUNCTION 實際就是在函數名前面添加 zif_,而後進行gdb調試code

第一步運行: gdb php
而後運行: break  zif_confirm_mydebug_compiled
終端提示:Function "zif_confirm_mydebug_compiled" not defined.
Make breakpoint pending on future shared library load? (y or [n]) 
輸入: y
輸入:  run /tmp/test.php
此時會回顯:Breakpoint 1, zif_confirm_mydebug_compiled (ht=1, return_value=0xb7bf0d44, return_value_ptr=0xb7bd6104, this_ptr=0x0, return_value_used=1)
    at /...../php-5.6.6/ext/mydebug/mydebug.c:56
而後輸入: l
顯示:
54      PHP_FUNCTION(confirm_mydebug_compiled)
55      {
56              char *arg = NULL;
57              int arg_len, len;
58              char *strg;
59
60              if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &arg, &arg_len) == FAILURE) {

其中文件/tmp/test.php的內容爲:開發

<?php

echo confirm_mydebug_compiled("hello world");

能夠看到,函數源代碼已經出來了,能夠使用經常使用的gdb命令進行調試了。

更多精彩原創內容進入http://www.codefrom.com/

相關文章
相關標籤/搜索