Visual Studio调试之符号文件
原文链接地址:http://www.cnblogs.com/killmyday/archive/2009/10/14/1582882.html
前面在不能设置断点的检查步骤和Visual Studio调试之断点进阶篇提到了调试符号文件及其作用,这篇文章我将要介绍调试符号文件的一些用法,如果你已经很熟悉调试文件的话,尽可以跳过本文。
调试符号文件为调试器提供了从二进制机器代码地址到源代码文本文件代码行的映射.因此有了符号文件,我们才能:
1. 设置断点,因为调试器需要符号文件提供的映射关系,将源代码行的行号转换成对应的机器代码的地址。
2. 查看程序堆栈,简单地说,就是调试器使用映射关系将堆栈里面的地址转换成包含这个地址的函数名。
3. 查看变量的值,对于机器来说,所有的变量都只是一个内存地址,程序在读取变量值的时候,只不过按照变量所属的类型来读取指定大小的内存而已。
4. 甚至调用程序的一些函数,比如原生(Native)程序,经过编译以后,在程序里面实际上只变成了一段机器代码。我们在立即窗口里面调用一个C++函数的时候,调试器需要将函数名翻译成对应的机器代码的起始地址,当然还要遵循一定的函数调用规则才能调用这个函数。
我们一个一个地看符号文件的功能:
查看程序堆栈
将Visual Studio以原生程序(Native)调试模式附加到一个已打开的记事本程序上(附:因为我的系统都是英文版,所以中文菜单都是对着英语直接翻译的,有的会翻译的不准确,所以我会把英文的命令附在后面),然后中断记事本进程的执行 — 通过点击VS菜单里面的“调试(Debug)”-“全部中断(Break All)”。
下面是具体的将VS附加到记事本进程的操作(不好意思,录制的视频太大,不知道怎么传)。
1. 点击Visual Studio里面的“工具(Tools)”- “附加到进程……(Attach to Process …)”。
2. 选择notepad.exe,当然你要保证“附加到… (Attach To…)” 文本框里面列出的调试类型是“原生程序(Native)”。
3. 点击确定以后,将Visual Studio附加到刚刚打开的记事本进程。
这个时候打开堆栈(Stack)窗口,你应该会看到类似下面的结果: 
上面的堆栈,我也看不懂(我的机器是64位的Windows 7,所以地址都是8个字节的)。因此我们需要一些东西来帮我们把难理解的地址(鸟语)翻译成有意义的文字,这个工作就是由符号文件来完成的。
因为记事本是操作系统自带的程序,我们当然没有办法自己生成它对应的符号文件啦,但是幸运的是,微软早就已经考虑到可能有一些人需要调试Windows内核—例如写驱动程序的程序员,因此微软公司已经将Windows的一些符号文件公开了,公开的地址在:
http://msdl.microsoft.com/download/symbols
在 Visual Studio里使用的方法是:
1. 点击菜单栏里面的“工具(Tools)”—“选项(Options)”。
2. 在“选项(Options)”对话框左边的列表框里面选择“调试(Debugging)”-“符号文件(Symbols)”。
3. 如果你的Visual Studio是Visual Studio 2008 SP 1,那么点击“从微软的符号文件服务器上加载符号文件(Load symbols from Microsoft symbols server)”就可以了。
4. 如果是其他版本-当然是低一些的版本,在右侧的“符号文件路径(Symbol file (.pdb) locations)”列表框里面添加新的一行,将上面的链接输入进去。
然后在“将符号文件缓存到这个文件夹(Cache symbols from symbol servers to this directory:)”文本框里输入你要缓存从服务器下载的符号文件的文件夹路径—毕竟那个服务器是在美国。如下图所示:
5. 点击“确定( OK)”
6. 对于听说英文没有困难的朋友,可以直接参考下面的链接学习如何设置:
http://support.microsoft.com/kb/311503/zh-cn
等待一段很长的时间以后—因为调试器要一个个下载记事本程序所引用到的所有动态链接库文件的符号文件,你应该可以看到类似下面的堆栈信息: 
这篇文章的描述里面,我希望你能够明白调试符号文件的重要性:
1. 如果没有调试符号文件,那么就不能查看堆栈—这话好像有点多余。但是很多时候,我们在分析验尸调试所保存的内存文件的时候,第一步要看检查的就是,程序崩溃的时候,堆栈是什么样子的,如果没有调试符号文件,那我们就什么也做不了了。
2. 那么调试符号文件是如何生成的呢?调试符号文件是由编译器生成的,因为编译器负责将文本格式的源代码文件翻译成二进制的程序,所以二者之间的映射关系编译再清楚不过了。每次重新编译的时候,编译器都会生成对应的调试符号文件。
生成调试符号文件的命令:
3. 例如一个客户跟你抱怨程序不能工作,出现了严重的错误(Bug),但是他正在运行的是1.0版本的程序,而你们公司却已经再开发2.0版本的程序了。由于源代码一般都不会给客户,这个时候如果能够找到原始的1.0 版本的源代码重新编译,然后安装到客户机重现一下固然是好,但是为什么不直接保存1.0版本的调试符号文件,在调试的时候,直接让调试器自己去找源代码呢?这里涉及到符号文件服务器和源代码文件服务器的合作问题,后面的文章里可能会介绍到。
Visual Studio调试之符号文件的更多相关文章
- [转]Visual Studio调试之符号文件
http://www.cnblogs.com/killmyday/archive/2009/10/14/1582882.html 前面在不能设置断点的检查步骤和Visual Studio调试之断点进阶 ...
- VISUAL STUDIO 调试
调试术语 Visual Studio调试之断点基础篇 Visual Studio调试之断点进阶篇 不能设置断点的检查步骤 Visual Studio调试之断点技巧篇 Visual Studio调试之断 ...
- Visual Studio调试之断点进阶篇
Visual Studio调试之断点进阶篇 在上一篇文章Visual Studio调试之断点基础篇里面介绍了什么是断点,INT 是Intel系列CPU的一个指令,可以让程序产生一个中断或者异常.程序中 ...
- 在 Visual Studio 调试器中指定符号 (.pdb) 和源文件
查找并指定符号文件和源文件:指定符号加载行为.使用符号和源服务器上:加载符号自动或在要求. 内容 查找符号 (.pdb) 文件 查找源文件 查找符号 (.pdb) 文件 说明 在之前的 Vis ...
- Visual Studio 调试系列10 附加到正在运行的进程
系列目录 [已更新最新开发文章,点击查看详细] 可将 Visual Studio 调试器附加到本地或远程计算机上正在运行的进程. 进程运行后,在 Visual Studio 中选择“调试” & ...
- Visual Studio 调试系列9 调试器提示和技巧
系列目录 [已更新最新开发文章,点击查看详细] 01 固定数据提示 如果你在调试时,经常将鼠标悬停在数据提示上,就可能想固定变量的数据提示,方便自己随时查看. 即使在重新启动后,固定的变量也能 ...
- 用Visual Studio调试Windows和驱动程序
由于本人能力有限,翻译不足之处敬请谅解,欢迎批评指正:sunylat@163.com Visual Studio版本:Visual Studio 2015企业版,中文环境. MSDN原文:https: ...
- 用Natvis定制C++对象在Visual Studio调试时如何显示
博客搬到了fresky.github.io - Dawei XU,请各位看官挪步.最新的一篇是:用Natvis定制C++对象在Visual Studio调试时如何显示.
- Visual Studio调试之避免单步跟踪调试模式
Visual Studio调试之避免单步跟踪调试模式 写完Visual Studio调试之断点进阶篇之后,想分享一下我常用的一些调试技巧,后面发现写之前,一些背景知识需要介绍一下. 下面是几篇今年2月 ...
随机推荐
- SHOPEX快递单号查询插件圆通V8.2专版
SHOPEX快递物流单号查询插件特色 本SHOPEX快递物流单号跟踪插件提供国内外近2000家快递物流订单单号查询服务例如申通快递.顺丰快递.圆通快递.EMS快递.汇通快递.宅急送快递.德邦物流.百世 ...
- android发布帖子类技术
最近练习一些关于发布帖子的技术,说来也简单,就学了一点皮毛吧!好了,下面就上代码吧! 首先设计服务器的访问类,大家都知道现在东西都要联网的嘛! JSONParser的类: public class J ...
- queue消息队列
class queue.Queue(maxsize=0) #先入先出 class queue.LifoQueue(maxsize=0) #last in fisrt out class queue. ...
- Java学习笔记十二:Java中方法的重载
Java中方法的重载 什么是方法的重载呢? 如果同一个类中包含了两个或两个以上方法名相同.方法参数的个数.顺序或类型不同的方法,则称为方法的重载,也可称该方法被重载了.如下所示 4 个方法名称都为 s ...
- LeetCode 二叉树的层次遍历 C++
给定一个二叉树,返回其按层次遍历的节点值. (即逐层地,从左到右访问所有节点). 例如:给定二叉树: [3,9,20,null,null,15,7], 3 / \ 9 20 / \ 15 7 返回其层 ...
- LINQ巩固
LINQ巩固 LINQ过滤运算符 Where 基于谓词函数过滤值 测试例子如下: public class TestModel { public string Name { get; set; } p ...
- 20145202马超《网络对抗》Exp3免杀 进阶
木马化正常软件,如通过改变机器指令.实现可免杀免防火墙提示的后门. 继上次实验3所做的代码在主函数里面加上一行调用就可以 改各种属性,这里我参考了郝浩同学的博客 最后我还是遇到了问题 后来发现虽然有那 ...
- 「暑期训练」「基础DP」 Common Subsequence (POJ-1458)
题意与分析 很简单:求最长公共子序列. 注意子序列与子串的差别:一个不连续一个连续.一份比较好的参考资料见:https://segmentfault.com/a/1190000002641054 状态 ...
- 电子取证-破解给定的SAM文件
给你一个SAM文件,如何提取出登录密码? SAM文件 ① LMHASH Administrator:500:0182bd0bd4444bf867cd839bf040d93b:c22b315c040ae ...
- 游戏测试中遇到的奇葩bug(不断整理中...)
1:跨服组织战中,不同服务器相同组织ID的敌对玩家不能造成伤害. 2:节日活动24点开启,角色不下线自然过渡到活动开启,界面显示异常 3:前端请求数据之后,不管是否接收到后端返回的数据,只要玩家点击仙 ...