跟踪调试易语言静态编译支持库的方法

作者:庄晓立(Liigo)

日期:2012-6-19

原创链接:http://blog.csdn.net/liigo/article/details/7677507

转载请注明出处:http://blog.csdn.net/liigo/


易语言支持库的动态库(*.fne)和静态库(*_static.lib)通常是同一套源代码,往往动态库调试成功了,静态库也应该没有什么问题。但不怕一万就怕万一,我还就真的遇到了普通编译(使用支持库动态库)运行正常,而静态编译(使用支持库静态库)后运行异常。遇到这种情况只能单独调试静态库。一开始我也没找到调试易语言支持库静态库的办法,只是采用弹信息框(MessageBox)、写日志文件之类的原始手段,不过这种办法实在太笨了,要依靠它定位并解决bug除了祈求好运气别无他法。残酷的现实逼迫我(liigo)必须摸索出一套调试易语言支持库静态库的办法,功夫不负有心人,终于被我找到。具体操作步骤如下:

1、首先需要设置易语言静态编译参数,修改 \tools\link.ini 文件,设置 show_command_line=yes,retain_intermediate_files=yes,删除相应行首的分号(;)。

2、编译支持库静态库的调试版(Debug版),覆盖\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步骤有误,回去检查一下,重来。

—— 全文完 ——


你可能感兴趣的:(C/C++,编译和链接,易语言,liigo,语言,linker,exe,bt,debugging,command)