人在江湖走,豈能不挨刀。今天人生又完整了一點:Emacs出現運行錯誤。一番折騰,正好學會一點簡單的排錯技巧。
本來JDE運行得上好。我把所有相關檔案送入SVN後(花了那麼多精力配置Emacs,不把心血放進版本控制軟體加每日多次冗餘備份,好比吳英真地披掛上10億珠寶,孤身到廣州火車站遛彎兒一樣不靠譜),重啟Emacs卻得到如下錯誤:error: JDEE plugin Lisp file jde-.svn.el missing。在JDE安裝目錄下做全文檢索搜尋,沒有這啥jde-.svn.el檔案。也沒有任何一份*.el代碼含有jde-.svn.el的字樣。考慮到Lisp的動態特性,以及.svn酷似SVN檔案樹下的中繼資料目錄名,開始猜測JDE的某個函數掃描某些檔案夾,把裡面所有的檔案都當成外掛程式載入。當然,俺是程式員,不會像黎叔一樣拿比人中黃還有想象力的猜想當證明,滿世界找人決鬥博取同情。排錯的過程如下:
- 根據Emacs的提示,用emacs –debug-init啟動Emacs。或者在初始檔案裡加入這句:(setq debug-on-error t)。setq是Emacs Lisp的關鍵詞,表示設定一全域變數。那個不起眼的“t”相當於Java裡的true。有了這句,以後Emacs遇到問題,就自動開啟內建調試器,建立一*backtrace*視窗,並列印出跟蹤結果。喜歡GUI的老大還可以用Options裡的菜單選項:
- 列印出的錯誤報表如下。不用管那些“byte-code”開頭的行。它們表示一段編譯過的*.el被載入,沒有什麼實質性的協助。我們的目的就一個:找到出錯的地方。這段訊息類似Java裡的stack trace,每一行是一例函數調用。從下到上,函數被依次調用。比如下面兩行就表示jde-pi-plugins()先被調用,接著jde-pi-plugins()調用jde-pi-plugin(“.svn”)
jde-pi-load-plugin(".svn")
jde-pi-load-plugins()
- 嗯,看到jde-pi-load-plugin(“.svn”),應該有8分希望了。現在的問題是,函數定義到底在哪個檔案裡。Emacs Lisp裡*.el一般是被require或者load-library這倆函數載入。所以我們自然找require(jde-plugins)裡的jde-plugins.el:
- 開啟jde-plugins.el後,C-s,尋找函數定義的開頭”(defun jde-pi-load-plugins”,果然找到了函數定義:
- 其實不用知道該函數的細節,抓住關鍵就行了。很明顯,下面這段代碼過濾掉常見的與plugin無關的目錄
- 我們照做就成,添加一行(not (string= file-name “.svn”)):
- 刪除掉jde-plugins.elc,重啟Emacs。錯誤消失。大功告成。
- 有耐心看到這裡的老大,俺奉上飯後甜點:要不是為了學習工具的話,這樣做就夠了:google JDE svn,答案就出現老。再次證明:菜鳥的問題,不算問題。