swoole做爲php的核心項目,php和swoole都具備必定的研究價值,因爲是c語言編寫的項目,要上手進行調試,那麼最好用的調試工具就是gdb了php
這個gdb調試工具功能強大,支持的選項也是很是多,下面就總結出來經常使用的命令html
在編譯時把調試信息編譯進生成的二進制文件中,須要給gcc編譯器加上-g參數,好比編譯php的Makefile中是這樣的 linux
加上-g
參數就已經有調試信息了,-O0是關閉gcc的優化,這個gcc優化後會在調試時丟失一部分調試信息,因此通常建議關閉
這樣在gdb裏面就能夠隨時查看當前執行到源碼的那個地方了,可以顯著提高調試的效率c++
gdb php
開始啓動gdb調試php命令行程序
使用list
命令,默認會定位到main方法所在的第一行被執行的代碼,能夠看到定位到了1186行,使用info line
指令能夠查看上面定位到的代碼所在的文件是"sapi/cli/php_cli.c"shell
在understand中打開php源碼進行驗證 segmentfault
由於是在linux下運行的,因此這個"PHP_CLI_WIN32_NO_CONSOLE"宏是不存在,第一行代碼是走到1186行的else分支是ok的,這就說明了gdblist
命令默認是定位到main方法的了
使用b
命令,或者全名break
命令能夠在任意函數開始位置進行斷點,好比c/c++的入口函數main處斷點,只需執行下面的命令就能夠了api
b main
複製代碼
操做效果以下 swoole
這樣斷點就加好了,運行php時就會在main方法處觸發這個斷點了使用命令info b
或者info break
就能夠查看目前全部的斷點了,效果以下 函數
sapi/cli/php_cli.c:1284
處再加個斷點
效果以下: 工具
能夠看到斷點已經成功加上了使用命令delete breakpoints 斷點編號
就能夠刪除斷點了,這個能夠自行研究
這個斷點操做的命令還有很是多,可使用命令help breakpoints
查看完整的斷點相關的命令清單
使用r
命令或者run
命令就是啓動這個被調試的php程序了,好比調試這個php命令:php test.php
<?php
// test.php
$a = '1';
echo $a;
複製代碼
上面這個命令是帶了參數 test.php因此,在gdb裏運行時也能夠把這個參數帶上,對應的gdb命令以下
run test.php
複製代碼
查看操做效果:
能夠看到成功命中了設置在1195行的斷點,這個說明在gdb裏啓動php成功了使用命令layout asm
能夠查看當前斷點所處位置的反彙編代碼,這個在高級分析時會常常用到,效果以下:
layout src
能夠切換到源碼視圖,這個視圖查看源碼很是方便
結合使用layout asm能夠實時對比彙編代碼和c代碼,有利於快速對比分析 使用這個
ctrl + x + a
命令能夠退出這個layout模式
上面使用layout模式查看彙編代碼,可是會打開新窗口,若是隻想查看當前斷點下面幾行彙編,可使用更快的diaplay命令,好比查看斷點下的10行反彙編代碼使用命令display/10i $pc
,查看效果以下:
可是這個display每次斷點都會輸出,可使用undisplay
命令進行刪除
在gdb中能夠很方便的使用p命令或者print命令來獲取當前斷點所處的上下文的變量的值
而後在這個1342處進行斷點,在1337處複製了一段字符串給ini_entries, 因此1342處ini_entries確定有值了
而後使用命令p ini_entries
查看ini_entries變量中的值
操做效果以下
成功的獲取到了ini_entries變量中的值是字符串 "html_errors=0\nregister_argc_argv=1\nimplicit_flush=1\noutput_buffering=0\nmax_execution_time=0\nmax_input_time=-1\n"編寫swoole協程測試代碼
// go.php
<?php
go(function () {
$a = '1';
echo $a;
});
echo '2';
複製代碼
好比在建立協程核心函數處斷點
b zif_swoole_coroutine_create
複製代碼
而後帶swoole擴展運行: run -dextension=swoole.so go.php
操做效果以下
能夠看到程序已經在swoole的swoole_coroutine_create成功斷點了而後就可使用gdb對swoole進行調試了
同時也能夠看到斷點時斷在了swoole-src/swoole_coroutine_util.cc:415行,能夠在understand中核對代碼是否一致
能夠看到在understand中代碼位置是ok的,這樣就能夠在gdb裏調試,在understand裏閱讀源代碼了😃使用c命令或者continue命令可讓程序執行到下一個斷點處
調試帶宏的函數,須要把宏展開獲取完整的函數名,才能下斷點
編譯swoole擴展時須要附加上調試信息,經過參數--enable-debug
實現
cd swoole-src
phpize
./configure --enable-debug
複製代碼