跨平台PHP調試器設計及使用方法——探索和設計____PHP

來源:互聯網
上載者:User

        在《跨平台PHP調試器設計及使用方法——立項》一文中,我確定了使用xdebug作為調試器外掛程式部分的基礎組件。xdebug提供了一個遠端偵錯的功能(相關資料可以詳見https://xdebug.org/docs/remote),我們這個項目便是基於這個功能實現的。(轉載請指明出於breaksoftware的csdn部落格)

        遠端偵錯是基於網路傳輸方式進行互動的一種調試方式,那麼其必定有服務端和用戶端兩部分組成。這兒的服務端和用戶端都是相對的,因為一個用戶端可能在和伺服器通訊後就變成了一個服務端,而服務端則在一次通訊後就變成了用戶端。xdebug在這個模型中屬於服務端,因為它是嵌入到PHP執行器內部,影響PHP執行流程的部分,這些核心功能肯定是作為服務端的一部分而存在。同時它也應該有接收和響應請求的功能。

        xdebug提供了兩種串連的方式,一種是固定地址單線串連。一種是未知地址多線串連。

        我們先看下固定地址單線串連,它的執行流程如下圖

嵌入在PHP執行程式中的Xdebug開啟了一個80連接埠 控制調試過程的IDE發起一次HTTP的調試請求 Xdebug根據配置項中的remote_host和remote_port欄位(也就是IDE所在機器的IP和IDE開放的連接埠),向IDE發起串連請求 IDE和Xdebug建立串連,相互連信 Xdebug應答2過程中的HTTP請求         上述方式存在一個問題,就是要在Xdebug裡配置好IDE的IP和PORT,這樣就只能有一台機器上的IDE可以與該Xdebug通訊。為了可以支援多使用者同時串連方式,Xdebug還提供了一種針對未知IP串連的方式,我們先看下流程圖:
嵌入在PHP執行程式中的Xdebug開啟一個80連接埠 控制調試過程的IDE發起一次HTTP的調試請求 Xdebug的配置項中藥配置remote_connect_back為1或者on,還要配置remote_port。Xdebug根據2中的請求解析出遠端IDE的IP,然後通過該IP和remote_port發起一次串連請求 IDE和Xdebug建立串連,相互連信 Xdebug應答2過程中的HTTP請求         面對這兩種方式,我們需要如何選擇呢。首先我們看一個問題,如果配置過netbeans和Xdebug串連的朋友,肯定記得netbeans中要配置代碼FTP地址。因為作為IDE需要能查看到遠程機器上這些要被執行的檔案(因為要展現給使用者看執行到哪兒了,哪兒要下斷點等)。雖然xdebug的source命令可以擷取當前執行檔案的內容,而對於一款調試器來說,我們往往需要很多尚未發生的內容。所以IDE要能訪問遠程檔案是必要的。         但是這一步驟,也將影響使用者配置調試器的進度。因為為了調試,我還要給遠程機器開啟一個FTP服務,還要佈建服務對應的本地地址,這些似乎都和我們要進行調試的行為無關。所以為瞭解決這個問題,我們索性在調試器中不放開編輯源碼的功能。同時我們將IDE和Xdebug放在同一台機器上,這樣IDE可以讀取本地的PHP執行的檔案,這樣也就不用開啟FTP服務了。於是,我們就選擇固定IP單線串連的方式。         這兒需要指出的是,我們在配置remote_host時肯定不能寫死一個IP。因為我們代碼和配置隨時會被拷貝到其他環境,所以寫死一些值將嚴重影響其適用性,於是我們可以使用localhost來代替固定IP

xdebug.remote_enable=On
xdebug.remote_handler=dbgp 
xdebug.remote_host=localhost
xdebug.remote_port=9000 
        通訊方式解決後,我們便需要關注通訊協定的問題。xdebug使用的是一個叫dpgp的協議,其協議文檔見https://xdebug.org/docs-dbgp.php。         這份協議文檔雖然比較長,但是還算簡單。作為行為請求的發起方,需要向Xdebug發送command -a value -b value……這種類型的請求內容,而Xdebug會返回一個XML內容。對於這種看似不對稱的請求類型造成的原因,文檔中解釋是說XML內容產生是容易的,但是解析卻需要其他的庫。然而作者明顯不想引入這些並不太重要的第三方庫。其實我覺得這種請求方式挺好的,它非常像我們使用的其他輸入式調試器,比如windbg。         接下來我們看下調試的過程 IDE擷取Xdebug支援的一些屬性(不同版本的Xdebug支援不同的功能,所以IDE要先探知它的支援什麼不支援什麼) IDE設定一些Xdebug屬性、斷點等資訊 Xdebug讓代碼運行起來,直到遇到斷點或者運行結束 如果遇到斷點,IDE可以向Xdebug詢問一些變數值,堆棧資訊,或者修改一些變數值等         我們再看下Xdebug文檔中一段比較類似人通話的過程,它也展現了整個調試過程的樣貌
IDE:  feature_get supports_async
DBG:  yes
IDE:  stdin redirect
DBG:  ok
IDE:  stderr redirect
DBG:  ok
IDE:  run
DBG:  stdin data...
DBG:  stdin data...
DBG:  reached breakpoint, done running
IDE:  give me some variables
DBG:  ok, here they are
IDE:  evaluate this expression
DBG:  stderr data...
DBG:  ok, done
IDE:  run
IDE:  break
DBG:  ok, breaking
DBG:  at breakpoint, done running
IDE:  stop
DBG:  good bye
        雖然看似整個協議非常簡單,但是我並沒打算去實現一套發送請求並解析XML返回結果的庫。我看了一下其他軟體的Xdebug通訊庫基本上都是調用了一套名叫pydbgp的Python實現庫,我也準備使用它。有時候還是非常必要站在巨人的肩膀上去實現一些事。         pydbgd的官方地址是http://jaredforsyth.com/pydbgp/。我們只需要取用下載包中的bin和dbgp兩個目錄下檔案。因為這塊的資料非常少,所以研究使用這套庫也花費了我一定的時間。而且這套庫實現中也存在不少缺陷,我也總是在不停探索和打patch中前行。好在經過一段努力,終於把它和Xdebug打通了。下面我展示一段pydbgp和Xdebug的互動過程
        第1部分是告訴IDE,調試用的IDE-KEY是什麼,要監聽哪個連接埠的。因為我是以netbeans的調試作為模板,所以我的IDE-KEY也是Netbeans和Xdebug互動的IDE-Key:netbeans-xdebug。當然這個值可以改成別的,但是要和xdebug的設定檔的idekey值一樣
xdebug.idekey="netbeans-xdebug"
        然後我啟動了監聽本地9000連接埠。這個9000連接埠號碼也不是隨便設定的,也要和Xdebug設定檔中的remote_port值一樣
xdebug.remote_port=9000 
        此時我們可以在網頁中發起一次請求,用於觸發php執行。這種觸發行為分為兩種,我會在之後做介紹。         網頁此時一直處在等待狀態,這表示Xdebug已經把PHP的執行過程給中斷了。於是我們可以進行下步操作。         我們執行sessions指令,用於查看目前有哪些串連已經建立過了。如上圖,pydbgp返回了串連資訊。當然這個展現不是Xdebug的未經處理資料——未經處理資料是XML的。         知道串連號後,我們使用select指令進入特定的串連。之後使用status查看調試的狀態。第一次status執行後,表示調試器處在開始狀態,這種狀態是一種中斷狀態,它還沒進入PHP代碼層。我們執行“步過”——step over操作一次,這個時候PHP執行便進入代碼了。使用stack_get指令查看當前的呼叫堆疊資訊,這些資訊中包括了棧號、檔案路徑、函數名。如果我們不關心之後的執行,就直接調用run指令,讓程式跑到底。這個時候調用status命令,可以看到調試器處在stopping的狀態。此時再run一下,本次調試就徹底結束了。結束後,我們使用quit指令退出當前調試。如果還有別的調試請求過來,則可以再調用sessions查看串連號,重複上述的調試過程。上圖中4是這個過程的一個體現。         如果不想進行調試了,則可以調用quit退出整個pydbgp。         pydbgp協助我們串連Xdebug,轉寄命令,解析返回的XML結果。但是它只提供了標準輸入方式的請求介面,我們沒法像直接調用API一樣調用這些介面。而且我也無意於將這套介面改成API的形式。於是我決定採用父子進程通訊的方式,父進程是我們的商務邏輯,子進程是pydbgp,父子進程通過重新導向輸入輸出來進行通訊。這是我最初的想法,但是最後重新導向的方案也被否掉了,因為python在不同平台上(windows和linux)對這種方式存在相容問題。這也是迫使我在項目後期老老實實使用標準socket去通訊,還好我之前代碼耦合做的比較好,替代方案很快就用上了。這兒感慨下,一些事情想時總是美好的樣子,而現實往往是曲折的樣子。當然隨著閱曆的增多,想像也會越來越靠譜,這就是經驗的作用。
        Xdebug給我們提供了很多調試的基礎功能。但是作為調試器,我們應該在這些基礎之上開發出更多組合性的功能,這樣可以協助使用者更快的發現問題。所以我們還需要對這些功能進行一些高階封裝組合,這些內容我們會在之後介紹。還有就是有些功能可能不是需要調試器提供的,比如記錄檔監控,所以這塊也將是我們調試器的一些協助工具功能。於是我們調試器的結構是這樣的

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.