vc6.0编译c++程序后在vc2008中调试的技巧(符号信息和链接)

来源:互联网 发布:pdf生成软件 编辑:程序博客网 时间:2024/05/13 09:52
 遇到的问题:
公司有个项目的源码是要vc6.0来编译的,我试过用vc2008来编译也是可以的,但编译出来dll文件拿去运行的时候是有异常的,因为加载的exe是第三方的,好像
没有源代码,出了错显示也是在exe里面不好跟进去。同事告诉我他们都是用vc6.0来编译dll,然后拿去用就没问题。可能第三方的很多exe和dll都是用vc6.0来
编译的,vc2008有些运行库有点变化不兼容了,没有exe的代码,也不好找出问题在哪里。看看同事们的意思也没有打算全部移到2008上面的意思,涉及的库太多
了吧,很多都是遗留下来的问题了,大家都懒的搞了。

vc6.0编译也可以了,不过我发现vc6.0这个东西可能还是太古老了,一个基本的“attach to process附加到指定进程”的功能竟然在 windows xp3上面用不了
的,点击之后出来的进程列表是空的。  搜索“vc6.0  attach process    empty  list” 可以找到这个应该是一个bug来的,MSDN的文章有说。

http://support.microsoft.com/kb/235434

 按照文章里面的解决办法
---------------------

解决方法 1
您应该能够附加到进程使用任务管理器:
启用在实时调试 (JIT),请执行下列操作:
在 Visual 的 c + + 中在 工具 菜单上的单击 选项。
在 调试 选项卡上进行确保选中了 仅在实时调试。
运行“任务管理器”,选择要附加到进程。用鼠标右键单击并选择 调试。

 
解决方法 2
运行任务管理器,获取为您要调试的进程的进程 ID。
在命令提示符处输入以下: msdev-p <processid>
这将启动 Visual c + + 中,并将附加到进程指定。
---------------------------

这两个解决办法都有一个问题,他都是新开一个vc工程,他让你可以附加到进程上去了,但没法打开相应的工程项目!  打开了相应的工程项目,有没法attach
他不像can008的调试器,你在任务管理器选择调试后,他是可以让你选择是不是在已经打开的工程中调试的。

按照微软文档的意思,这个vc的bug已经在后面的pack里面修复了,我重装了一个vc6 pack6的,昨天还是可以在那个 “attach to process”列表里面看到进程的
,我还以为是可以了,重启电脑之后,今天来了一看那个列表还是空的啊,不知道是不是环境变量有变化了? 反正这鬼东西就是用不了啦,vc6.0也太古老了一
点,没办法。

 

 只好在vc6.0里面编译,然后看看能不能在 vc2008里面调试了, vc2008的attach to process功能一向很正常,界面都好看一些。不过好像在dll制定的dll的相
应函数中断下来,下断点这些都没问题,就是local auto变量查看不了,说是没有符号信息。调用堆栈和汇编检查,确实都表明之制定的函数来的,但不能总看
汇编吧!!!

 

关于VC调试符号的说明
====================
1. 编译的时候给cl.exe 制定 /ZI 编译选项

 在visual studio 里面设置选项。

工程属性 -> C/C++ -> "General" -> Debug Information Format -> Program Database for Edit And Continue

参考

http://msdn.microsoft.com/zh-cn/library/958x11bc(v=vs.100).aspx

/ZI

以支持“编辑并继续”功能的格式产生如上所述的程序数据库。 如果想使用“编辑并继续”调试,则必须使用此选项。 因为大多数优化与“编辑并继续”不兼容,所以使用 /ZI 会禁用代码中的所有 #pragma optimize 语句。

 /ZI 会导致在编译中使用 /Gy(启用函数级链接) 和 /FC(所诊断源代码文件的完整路径)。

/ZI 与 /clr(公共语言运行时编译) 不兼容。

---------------------------------------------------

2. 链接的时候给link.exe 制定编译选项 /DEBUG 和 /PDB:filename

 工程属性 -》”configuration properties “ -》 “Linker” -》“debugging” -》 “generate program datbase file ”制定了 生成的pdb符号信息文件的具体位置。 “Generate Debug Info” 设置为 yes

 解释参考

http://msdn.microsoft.com/zh-cn/library/xe4t6fc1(v=vs.90).aspx

http://msdn.microsoft.com/zh-cn/library/kwx19e36(v=vs.90).aspx

 
/DEBUG 选项创建 .exe 文件或 DLL 的调试信息。

链接器将调试信息放在程序数据库 (PDB) 中。它在后面的程序生成期间更新 PDB。

为调试创建的 .exe 文件或 DLL 包含相应 PDB 的名称和路径。调试器在您调试程序时读取嵌入的名称并使用 PDB。链接器使用程序的基名称和扩展名 .pdb 命名程序数据库,并嵌入它的创建路径。若要重写该默认值,请设置 /PDB 并指定不同的文件名。

编译器的仅限行号 (/Zd) 或 C7 兼容 (/Z7) 选项使编译器将调试信息保留在 .obj 文件中。还可以使用程序数据库 (/Zi) 编译器选项将调试信息存储在 .obj 文件的 PDB 中。链接器首先在写入 .obj 文件的绝对路径中查找对象的 PDB,然后在包含 .obj 文件的目录中查找。不能指定对象的 PDB 文件名或链接器的位置。

指定 /DEBUG 时暗含 /INCREMENTAL。

DEBUG 将 /OPT 选项的默认值从 REF 更改为 NOREF 以及从 ICF 更改为 NOICF(因此,需要显式指定 /OPT:REF 或 /OPT:ICF)。

有关 .PDB 和 .DBG 文件的更多信息,请参见知识库文章 Q121366,INFO: PDB and DBG Files - What They Are and How They Work。可以在 MSDN Library 中或http://support.microsoft.com/default.aspx?ln=zh-cn 上找到知识库文章。

无法创建包含调试信息的 .exe 或 .dll。调试信息始终放在 .pdb 文件中。

 

在 Visual Studio 开发环境中设置此链接器选项

 
打开此项目的“属性页”对话框。有关详细信息,请参见设置 Visual C++ 项目属性。

单击“链接器”文件夹。

单击“调试”属性页。

修改“生成调试信息”属性。

 以编程方式设置此链接器选项

 -------------------------------------------

3.“attach to process” 或者附加到进程。在“module”窗口里面找到对应的dll,可以看到pdb符号文件是不是加载成功。右键会有“symbol load informations”  “symbol setting” 两个选项。

或者中断后 "call stack"  窗口里面,右键也相应的 dll的函数名 ,会有“symbol load informations”  “symbol setting” 两个选项

 这个也会打开第4步的那个窗口。

在这个窗口里面可以手工设置加载自己制定的pdb 符号文件。

如果发现pdb已经找到,但是还没法在制定的源码下断点,请检查前面的第一个第二步的设置,特别是这个 /ZI 选项一定要制定,不然在这个窗口里面看到了pdb已经加载,但却没发下断点,提示没有符号信息。另外如果使用的命令行或者makefile的话的link.exe一定要和visual studio的版本对应,vc 2010就用

用vc2010的link.exe.

 -----------------------------------------------

4. “tools” -》 “options” -》 “debugging”  -》 “symbol” 那里可以指定 加载 特定的符号

 ------------------------------------------

5. 另外vc2008 编辑修改文件后,没法下断点,提示源码行没有匹配的情况。

重新编译一下,如果还不解决问题,好像是个bug,选中文件的所有行,然后利用菜单里面的  edit ——》advance -》 format selection 把该文件的所有的代码都格式化一下。再保存,重新编译就可以了。

 
------------------------------------------

6. MSDN里面关于pdb文件的说明

 PDB Files (C++)

 http://msdn.microsoft.com/en-us/library/yd4f8bd1(v=VS.90).aspx


=================================================

 我检查了一下,vc6.0编译出来的调试信息pdb文件其实已经被找到加载了的,至于怎么会可以下断点在源码的指定行数上面,而符号信息都是没有,我怀疑是pdb

文件格式的问题吧,vc6.0的pdb文件是由就版的link.exe生成,vc2008是用新版本的link.exe,导出的pdb文件格式不一样,微软这产品做得不好啊,不兼容久版
本的格式。

 
我先开始是想先用vc6.0的cl.exe来编译出来 *.obj 文件,然后用vc2008 的link.exe来链接,这样链接一步得到的pdb文件格式就是新版的格式了,vc2008调试

 时也就可以正确加载了。使用vc6.0编译的dll也能够和 第三方exe兼容有可以调试,那就最好了。

但是粗略试了一下,链接的时候不知道有很多符号找不到,可能和编译时的依赖库和运行时库不同,两个版本合在一起,就会很多问题,

看上去解决这些问题也挺麻烦的。

我就另外用来个投机取巧的办法,直接用vc2008的link.exe复制过来替换vc6.0目录下的link.exe

 
 vc2008目录下有三个文件

 link.exe

link.exe.config

mspdb80.dll

 

直接复制过来替换

C:\Program Files\Microsoft Visual Studio\VC98\Bin 目录下的LINK.EXE文件。

然后在vc6.0里面编译他就自动用新的link.exe了,生成的也是新的pdb文件格式了,再在vc2008调试时就可以显示 local auto窗口的变量了,暂时没发现其他问

题,就先这样子用吧。

 
===============

其实不用替换上面link.exe 文件,先在vc6.0中导出一个makefile,然后修改make中断link.exe为 2008的link.exe就可以了

 vc6.0中 “project”  -》 “export makefile”

然后在工程目录下生成一个新的makefile文件

 *.mak

把他改名为makefile

然后修改makefile文件里面的LINK32的值为 vc2008的link.exe的全路径

然后用

nmake ALL  编译就可以了。

 
就我这个问题,关键是设置好path环境变量,保证 cl.exe是vc6.0的,然后mspdb80.dll 文件可以在%path%找的到就可以了。

我是这样建一个*.bat文件

 cmd /k "set path=%path%;C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE"

 然后执行这个bat,再执行nmake all编译就可以了。
 

原创粉丝点击