跟踪调试易语言静态编译支持库的方法
作者:莊曉立(Liigo)
日期:2012-6-19
原創鏈接:http://blog.csdn.net/liigo/article/details/7677507
轉載請注明出處:http://blog.csdn.net/liigo/
易語言支持庫的動態庫(*.fne)和靜態庫(*_static.lib)通常是同一套源代碼,往往動態庫調試成功了,靜態庫也應該沒有什么問題。但不怕一萬就怕萬一,我還就真的遇到了普通編譯(使用支持庫動態庫)運行正常,而靜態編譯(使用支持庫靜態庫)后運行異常。遇到這種情況只能單獨調試靜態庫。一開始我也沒找到調試易語言支持庫靜態庫的辦法,只是采用彈信息框(MessageBox)、寫日志文件之類的原始手段,不過這種辦法實在太笨了,要依靠它定位并解決bug除了祈求好運氣別無他法。殘酷的現實逼迫我(liigo)必須摸索出一套調試易語言支持庫靜態庫的辦法,功夫不負有心人,終于被我找到。具體操作步驟如下:
1、首先需要設置易語言靜態編譯參數,修改 <e>\tools\link.ini 文件,設置?show_command_line=yes,retain_intermediate_files=yes,刪除相應行首的分號(;)。
2、編譯支持庫靜態庫的調試版(Debug版),覆蓋<e>\static_lib\目錄下的同名文件。注意,這里生成的靜態庫,應該使用resym.exe處理,參見易語言SDK\static_docs\。
3、用易語言編寫一個程序,調用該支持庫命令,然后靜態編譯。此時鏈接器可能會提示找不到 libcmtd.lib, libcpmtd.lib, libcimtd.lib 之類的C/C++運行庫的Debug版,這是因為網上下載的?vc98linker 沒有帶調試版的庫,不過沒關系,我們去VC6安裝目錄去找,都可以找到,復制到?vc98linker 的 lib 目錄就OK了。在易語言自動定位并采用本機安裝的VC6鏈接器的情況下,不需要本步驟。
4、然后繼續靜態編譯,鏈接器應該會提示 libcmtd.lib 和 libcmt.lib 兩者存在符號沖突,靜態編譯失敗。原因很好理解,我們的Debug版靜態庫要鏈接調試版的C運行庫libcmtd.lib,而易語言核心庫的靜態庫是Release版的,它要鏈接發布版的C運行庫libcmt.lib。不過沒關系,我們后面的步驟將通過給鏈接器附加命令行參數的方法予以解決。
5、由于我們先前第1步驟已經設置了“顯示鏈接器命令行”(?show_command_line=yes),所以在第4步的時候,易語言會輸出鏈接器(linker)的命令行,大致如下:
"C:\Program Files\e\vc98linker\bin\link.exe" "E:\liigo\temp\bt_static.obj" "C:\Program Files\e\static_lib\krnln_static.lib" "C:\Program Files\e\static_lib\btdownload_static.lib" "C:\Program Files\e\static_lib\btdownload\gzip.lib" kernel32.lib user32.lib gdi32.lib winmm.lib msimg32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib "E:\liigo\temp\bt_static.res" /LIBPATH:"C:\Program Files\e\static_lib" /nologo /machine:I386 /subsystem:windows /out:"E:\liigo\temp\bt_static.exe"
把該命令行復制出來,粘貼到控制臺窗口(開始 - 運行 - cmd.exe),然后在命令行后面多加一些參數,/nodefaultlib:libcmt.lib /pdb:"estatic.pdb" /debug /pdbtype:sept,如下:
C:\Users\liigo>"C:\Program Files\e\vc98linker\bin\link.exe" "E:\liigo\temp\bt_static.obj" "C:\Program Files\e\static_lib\krnln_static.lib" "C:\Program Files\e\static_lib\btdownload_static.lib" "C:\Program Files\e\static_lib\btdownload\gzip.lib" kernel32.lib user32.lib gdi32.lib winmm.lib msimg32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib "E:\liigo\temp\bt_static.res" /LIBPATH:"C:\Program Files\e\static_lib" /nologo /machine:I386 /subsystem:windows /out:"E:\liigo\temp\bt_static.exe"?/nodefaultlib:libcmt.lib /pdb:"estatic.pdb" /debug /pdbtype:sept
這里解釋一下:新增的參數?/nodefaultlib:libcmt.lib 是為了解決libcmt.lib與libcmtd.lib之間的符號沖突,如果還有其他庫與libcmtd.lib有符號沖突,用同樣的方式解決;新增的其他參數?/pdb:"estatic.pdb" /debug /pdbtype:sept 是為了給靜態編譯后的EXE添加調試信息,其中參數 /pdb:"estatic.pdb" 指定了要生成的調試文件的文件名(可帶路徑)。經我(Liigo)測試,即使這里指定的.pdb文件與最終編譯生成的EXE不在同一目錄也不是相同的文件名,VC6調試器也照樣可以定位并加載該.pdb文件。所以我們不需要特別介意此處.pdb的路徑和文件名;但話說兩邊,如果今后一旦調試器定位不到.pdb,我們應該回來修改 /pdb: 參數,指定一個與EXE在同一目錄且主文件名相同的.pdb(具體到本例就是 /pdb:"E:\liigo\temp\bt_static.pdb")。
6、回車執行第5步驟的鏈接命令,于是靜態編譯成功了(如果一切順利),我們得到了含有調試信息的EXE可執行程序。去哪里找這個EXE?就是第4步驟靜態編譯時你在易語言中輸入的目錄和文件名啊。
7、運行上一步驟生成的EXE程序,然后按系統熱鍵 Ctrl+Alt+Del 打開任務管理器,找到該EXE進程,鼠標右鍵單擊之,在菜單中選擇“調試”,在接下來的確認對話框中點擊“附加調試進程”(Attach to process)按鈕,于是VC6啟動并開始調試此EXE進程,它會自動定位并加載第5步驟中生成的.pdb調試信息文件。注意,本步驟要求事先設置VC6為系統JIT調試器,設置方法為:VC - Tools - Options - Debug,選中“Just-in-time debugging”。8、通過VC6主菜單 File - Open 打開該支持庫靜態庫的源代碼文件,按 F9 設置斷點,開始調戲程序吧XD。如果按F9無反應,無法設置斷點,應該是第2步驟或第5步驟有誤,回去檢查一下,重來。
—— 全文完 ——
總結
以上是生活随笔為你收集整理的跟踪调试易语言静态编译支持库的方法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: PHP 手册
- 下一篇: React-Router面试题汇总