用DBGPavim在Vim中除錯PHP/Python程式
本文主要介紹如何在伺服器上用VIM + XDebug除錯PHP程式,目前雖然有不少介紹如何用Eclipse + XDebug在開發人員工作機上除錯PHP的文章,但對於如何系統的配置VIM + XDebug還是比較少的,而且目前關於VIM設定的文章都用一個比較老的外掛。這裡主要介紹一個新外掛DBGPavim,它相對於老的一些外掛有很多優勢。同時該外掛可完美的用於Python程式的除錯。另外VIM + XDebug相對於Eclipse + XDebug也有不少優勢,將在文章講述。
實現原理
DBGp是偵錯程式後臺和偵錯程式介面通訊的一種協議,用於多種指令碼語言的除錯。XDebug是用於除錯PHP的DBGp實現。VIM要和XDebug互通,實現PHP的除錯,需要能夠理解DBGp協議,並能傳送DBGp指令。DBGPavim就是這樣一個外掛,它使VIM能夠接受DBGp請求,併傳送DBGp指令,以達到除錯目的。DBGPavim的名字源於DBGp@VIM。
ActiveState提供了用於除錯Python/Ruby的DBGp實現Komodo Remote Debugging Package,後面有一節將講到如何使它和VIM互通,以除錯Python。使用者將能以此類推出如何除錯ruby/nodejs等指令碼語言。
配置XDebug
- 安裝XDebug可以參考http://xdebug.org/docs/install。
- 編輯php.ini,加入以下兩行:
zend_extension=/path/to/xdebug.so xdebug.remote_enable=1
- 編輯你的httpd.conf,加入以下行:
php_value xdebug.remote_autostart 1
- 注:這一行並非必須的,如果不加這一行,你需要在訪問HTTP伺服器的URL里加上XDEBUG_SESSION_START=1的引數,如: http://localhost/index.php?XDEBUG_SESSION_START=1。
如果有多個開發人員同時需要除錯不同的VirtualHost,可以在你的VirtualHost段中加入以下行:
php_value xdebug.remote_port 9009
注:這裡的9009就是VIM作為DBGp伺服器應當監聽的埠,不同的開發人員在不同的VirtualHost中用各自不同的埠號。這個埠號和下一節提到的dbgPavimPort要一致。不加這一行,預設的埠號是9000。
最後可通過phpinfo.php檢查你的XDebug配置是否正確,你必須能夠看到以下這些行的值如下(主要是前兩列):
xdebug.remote_autostart On Off xdebug.remote_enable On On xdebug.remote_handler dbgp dbgp xdebug.remote_host 127.0.0.1 127.0.0.1 xdebug.remote_port 9009 9000
phpinfo.php檔案內容如下:
<?php phpinfo(); ?>
配置VIM + DBGPavim
DBGPavim外掛本身是用Python實現的,所以需要你的VIM支援Python 2.7。開啟你的VIM,輸入命令
:version
如果能看到“+python”,說明你的VIM是支援Python的。 如果看到的是“-python”,說明你的VIM不支援Python,你可以按如下步驟編譯自己的VIM:
- 安裝Python 2.7
- export path=/path/to/python2.7/bin:$PATH
- 用以下命令編譯VIM:
./configure --prefix=/opt/vim --enable-pythoninterp --with-python-config-dir=/usr/lib/python2.7/config make make install
注:這裡的/usr/lib/python2.7/config取決於你把Python2.7安裝到什麼位置。
從這裡或者這裡下載DBGPavim,放到你的~/.vim目錄下,並編輯的你的~/.vimrc,加入以下兩行:
let g:dbgPavimPort = 9009 let g:dbgPavimBreakAtEntry = 0
注:這裡的9009和上一節的9009要一致,如果上一節沒有配置xdebug.remote_port,這裡也不需要配置,因為它們都會使用預設的9000。 dbgPavimBreakAtEntry=0告訴VIM不在入口處停下,這樣只會在斷點處停下。
你可以重新啟動VIM,按F5檢查你的DBGPavim配置是否正確。如果你配置成功的話,你會做VIM視窗的右下角看到提示資訊如下:
bap-LISN-9009
它表示VIM目前正在監聽9009埠,bap說明它只會在斷點處停下,其他提示資訊格式如下:
<bae|bap>-<LISN|PENDn|CONN|CLSD>
斷點狀態
bae Break At Entry,在入口處停下 bap Break only At breakPoints,只在斷點處停下
偵錯程式狀態
LISN 偵錯程式已啟動,正處於監聽狀態。 PEND-n 偵錯程式已捕捉到連線請求,可以按F5進入除錯模式了。 CONN VIM正處於除錯模式中。 CLSD 偵錯程式已停止。
在Apache環境下除錯PHP
- 現在確認配置正確後,可以用VIM開啟你需要除錯的檔案,跳到你需要除錯的行,按F10設定當前行為斷點,並按F5啟動偵錯程式。
- 用瀏覽器訪問會呼叫相應PHP檔案的URL,你會看到VIM狀態列裡的的提示資訊變成:
bap-PEND-1
- 它告訴你已經有一個連線被攔截,可以按F5開始除錯了。
- 按F5進入除錯模式,你會看到VIM視窗被分成三部分:左上為原始碼視窗,右上為變數檢視視窗,下方為呼叫堆疊視窗。在原始碼視窗裡,把游標定位到某一個變數上面按F12,在變數檢視視窗就能看到該變數的值,如果該變數不是簡單變數,其成員也會顯示出來。如果該變數的某個成員仍不是簡單變數,該行後面會出現一個加號,在該行按Enter鍵,該成員的值將被繼續展開。如果你想直接檢視某個變數的成員變數,可以按v切換到visual模式,選中該成員再按F12,比如$this->login。在堆疊視窗,當你在某一行按回車,將跳到該層。最上面一行是最底層,最下面一行是最頂層。切換呼叫堆疊的層次,可以幫助你檢視各個層次的變數,比如有些全域性變數只有在最頂層才能看到。對於原始碼中沒有出現的變數,你可以通過命令:Pg來檢視,比如:
g $this->memberShip
- 你可以開始你的除錯了,隨時按F1可調出幫助視窗,再次F1就關閉幫助視窗。
除錯命令列啟動的PHP程式
如果你需要除錯命令列啟動的PHP程式,也需要保證PHP程式端的設定是正確的。這些設定可以像前面一樣在php.ini中設定,也可以通過命令列引數來設定。比如:
php -dxdebug.remote_autostart=1 -dxdebug.remote_port=9009 test.php
如果你的命令列使用的ini和apache中php5_module使用的ini是一樣的(通常情況是這樣的),你不需要在引數中再來做這些設定。但如果你在ini中的設定是放在某個virtualhost段裡,你仍然需要加上這些設定。 你可以通過命令列:
php --ini
來檢視你的命令列用的是哪個ini。
接著你可以使用命令:
php -r "phpinfo();"|grep xdebug.remote_
來檢查你的XDebug設定。
基本步驟如下:
- 用VIM開啟你需要除錯的PHP檔案,F10設定斷點,F5啟動除錯監聽。
- 從命令列執行php程式如上。
- 回到你的VIM視窗,將看到提示資訊為PEND-1。
- 按F5進入除錯模式。
DBGPavim提供一個:Dp命令簡化命令列程式的除錯。只需開啟你的PHP檔案,輸入命令:Dp即可。
除錯Python程式
前面說過VIM + DBGPavim作為DBGp協議的伺服器,可以與XDebug協同工作,也可以與ActiveState提供的Komodo Python Remote Debugging Client協同工作,實現Python程式的除錯,具體步驟如下:
- 從這裡下載安裝Komodo Python Remote Debugging Client,把解壓後的bin目錄加到你的PATH路徑中,注意bin目錄下的pydbgp檔案。
- 用VIM開啟你需要除錯的Python檔案,F10設定斷點,F5啟動除錯監聽。
- 通過pydbgp執行你的Python程式,如
pydbgp -d 127.0.0.1:9009 test.py
-
- 注:這裡的9009埠就相當於上面為PHP除錯時設定的xdebug.remote_port,需要和dbgPavimPort保持一致。
- 回到你的VIM視窗,將看到提示資訊為PEND-1。
- 按F5進入除錯模式。
上面的:Dp命令同樣適用於Python除錯,下圖為Windows 7下用GVIM + pydbgp除錯Python的截圖。
VIM + DBGPavim相對於Eclipse + XDebug的優勢
大多數伺服器不會啟動XServer,無法在伺服器上啟動Eclipse。如果在開發人員工作機上啟動Eclipse + XDebug,就相當於把DBGp伺服器在工作機上執行,你需要設定路徑對映,也就是HTTP Server執行的一份程式碼在伺服器上,Eclipse除錯時開啟的是一份程式碼,在工作機上,要保證這兩份程式碼能對應上需要對映路徑。當程式規模不大時,問題不大,當程式規模大時,會比較麻煩,而且要保證程式碼的同步,否則會序列。
同時可以遭遇網路防火牆之類的問題。
VIM + DBGPavim也是支援遠端除錯的,但同樣避免不了路徑對映的設定,如下:
let g:dbgPavimPathMap = [['D:/works/php','/var/www'],]
DBGPavim相對於其他外掛的優勢
DBGPavim源於VIM早期的一個DBGp外掛http://www.vim.org/scripts/script.php?script_id=1152,從這個外掛還衍生出其他一些DBGp外掛。但DBGPavim重寫了作為偵錯程式後臺的DBGp伺服器,非同步監聽,使得VIM在監聽DBGp的同時不妨礙使用者與VIM之間的互動。使用者按F5啟動除錯監聽後,可繼續使用VIM,隨時可按F6停止監聽。
DBGPavim會監聽所有來自DBGp客戶端如XDebug、pydbgp的DBGp連線,不像其它外掛只能捕獲第一個連線。這對於大規模的WEB程式是必須的,因為現在的一次網頁載入通常會觸發多個HTTP請求,而我們需要除錯的可能來自其中的任何一個。 同時DBGPavim支援只在斷點處停下,其它的外掛都是在入口處停下,需要程式設計師一步步跟蹤進去。這省了開發人員很大的麻煩,而且避免出錯後一次次的重啟除錯。
相信你也已經發現,DBGPavim可以與Windows下的GVIM一起工作,並且工作的很好。
DBGPavim的詳細使用參考
VIM normal模式下
F5 啟動除錯監聽,或者有可除錯連線時進入除錯模式。 F6 停止除錯監聽。 F8 切換dbgPavimBreakAtEntry的值,按這個鍵你可以看到狀態列提示資訊在bae和bap之間切換,即是否在PHP程式入口處停下。 F10 在當前行設定或刪除斷點,在除錯模式下同樣適用。
除錯模式下
F1 開啟或關閉幫助視窗 F2 單步進入 F3 單步跳過 F4 單步退出 F5 繼續執行直到下一個斷點,如果後續沒有斷點就退出除錯模式。 F6 停止除錯,這個按鍵就導致VIM退出除錯模式,並且停止除錯監聽。 F7 除錯時執行php語句,按下F7後,使用者可在變數檢視視窗輸入php語句,回車後執行。 F9 最大化某個子視窗,或者重置視窗布局。 F11 檢視當前執行環境下的所有變數的值,在不同的堆疊層次,會有不同的結果。 F12 檢視游標下的變數的值。
以上功能鍵為預設配置,你如果習慣多數瀏覽器的按鍵設定,可以把下面的程式碼加入你的.vimrc中:
let g:dbgPavimKeyRun = '<F8>' let g:dbgPavimKeyStepOver = '<F10>' let g:dbgPavimKeyStepInto = '<F11>' let g:dbgPavimKeyStepOut = '<F12>' let g:dbgPavimKeyPropertyGet = '<F3>' let g:dbgPavimKeyContextGet = '<F4>' let g:dbgPavimKeyToggleBp = '<F9>' let g:dbgPavimKeyToggleBae = '<F5>' let g:dbgPavimKeyRelayout = '<F2>'
VIM命令,所有命令只有第一個字母為大寫。
:Bl 列出所有斷點 :Bp 與F10功能相同 p 這個命令可用於快速除錯當前檔案,它實現瞭如下功能: 1. 檢查命令列下XDebug/pydbgp的設定是否正確 2. 啟動偵錯程式監聽 3. 用php/pydbgp執行當前檔案 g <longfoo> 檢視較長變數的值,比如:Pg $this->savings[3] :Up 呼叫堆疊往上一級 n 呼叫堆疊往下一級 :Wc [$foo] 開啟/關閉對變數$foo的監視。如果沒有引數,就監視當前執行環境下的所有變數。 :We <foo> 開啟/關閉對語句foo的監視,即每一單步後自動執行foo語句。 :Wl 列出所有被監視的變數或語句。 :Children <n> 對於陣列預設顯示前1024個元素,這個命令可以修改。 epth <n> 對於複雜變數,預設只顯示下一層成員,這個命令可以設定限制多層。 :Length <n> 對於字串變數,預設執行顯示前1024個字元,這個命令可以設定顯示長度。
相關文章
- Java程式中除錯Python程式方法Java除錯Python
- vi/vim使用進階: 在VIM中使用GDB除錯 – 使用vimgdb除錯
- 在Visual Studio中快速啟動除錯Web應用程式除錯Web
- Python 程式碼除錯—使用 pdb 除錯Python除錯
- scrapy在pychram中除錯除錯
- 在 Istio 中除錯 503 錯誤除錯
- 用GDB除錯程式除錯
- 在MyEclipse中用debug除錯應用程式Eclipse除錯
- PHP CLI應用的除錯原理PHP除錯
- 使用Eclipse除錯PHP應用Eclipse除錯PHP
- 在Intellij IDEA下用X-debug除錯PHPIntelliJIdea除錯PHP
- repr除錯python程式除錯Python
- [原] 在 PhpStorm 中使用 Xdebug 遠端除錯 PHP 程式(框架/原生均適用)PHPORM除錯框架
- Flutter 應用程式除錯Flutter除錯
- 用GDB除錯程式(六)除錯
- 用strace除錯程式(zt)除錯
- Python 程式碼除錯技巧Python除錯
- python 程式的的除錯Python除錯
- 遠端除錯在Linux車機中的應用除錯Linux
- 使用debugger在dojo小部件中除錯程式碼除錯
- 在Eclipse下除錯GlassFish程式Eclipse除錯
- 用WinDBG遠端除錯程式除錯
- 用GDB除錯程式(二) (轉)除錯
- 用GDB除錯程式(四) (轉)除錯
- 用GDB除錯程式(三) (轉)除錯
- Python之PySnooper程式碼除錯PythonOOP除錯
- Python常用的程式除錯方法Python除錯
- ***php除錯總結PHP除錯
- 在 Python 除錯過程中設定不中斷的斷點Python除錯斷點
- 學會用core dump除錯程式錯誤除錯
- F407在RAM中除錯除錯
- [譯]用 LLDB 除錯 Swift 程式碼LLDB除錯Swift
- PHP 程式碼除錯跟蹤工具 YtracePHP除錯
- python 除錯Python除錯
- PHP 除錯利器之 PHPDBGPHP除錯
- 除錯應用程式記憶體中的神祕問題除錯記憶體
- Windbg在應用層除錯漏洞時的應用除錯
- 在linux下用vim編寫一個C程式LinuxC程式