使用 gdb 除錯 PHP 擴充套件
阿新 • • 發佈:2019-02-14
php的擴充套件使用c/c++開發,可以很容易的使用gdb進行除錯。具體步驟如下: 首先編譯php的時候需要加上** --enable-debug**引數
./configure --enable-debug
make && make install
在我的ubuntu機器上面測試,擴充套件的目錄預設為 /usr/local/lib/php/extensions/debug-non-zts-20131226/
這樣進行php的原始碼除錯也很方便。
下一步進行擴充套件建立,進入php原始碼的ext目錄,執行
./ext_skel --extname=mydebug
當前目錄下會自動生成mydebug
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
這樣就表示該擴充套件能夠進行除錯了,然後編譯該擴充套件,使用命令
phpize
./configure --enable-debug
make && make install
這裡的 phpize
和 php-config
需要事先配置好環境變數,然後載入該擴充套件。在我的機器上面地址為/usr/local/lib/php/extensions/debug-non-zts-20131226/
。進入mydebug擴充套件原始碼目錄,預設生成的函式為confirm_mydebug_compiled
,定義在 mydebug.c
,擴充套件自動生成的函式。
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除錯
第一步執行: 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命令進行除錯了。