Visual_Studio调试.doc

上传人:sk****8 文档编号:3502227 上传时间:2019-06-01 格式:DOC 页数:14 大小:467KB
下载 相关 举报
Visual_Studio调试.doc_第1页
第1页 / 共14页
Visual_Studio调试.doc_第2页
第2页 / 共14页
Visual_Studio调试.doc_第3页
第3页 / 共14页
Visual_Studio调试.doc_第4页
第4页 / 共14页
Visual_Studio调试.doc_第5页
第5页 / 共14页
点击查看更多>>
资源描述

1、Visual Studio 调试之断点基础篇我曾经问过很多人,你一般是怎么调试你的程序的?F9, F5, F11, F有很多书和文章都是介绍怎么使用 Visual Studio 编写 WinForm 啦,、ASP.NET 之类的程序;知道如何编写固然重要,但是我觉得程序员可能只会花费 30%的时间在编写代码上,剩下的大部分时间都是在调试程序。在网上看到很多人介绍 Windbg 的用法,但是没有看到几篇讲解使用 Visual Studio 调试的文章。Windbg 固然强大,但是问题是它的学习曲线太陡了,而且很多调试并不需要使用 Windbg 来调试(当然啦,并不是指我不会Windbg 调试啦

2、这是以后的调试系列文章将要讲的),为什么不使用我们最熟悉的Visual Studio 来进行调试呢?调试嘛,无非就是要看看程序在运行时候,内部的状态,例如一些变量的值是多少,看一看程序调用的路径啦之类的。当然最直接的方式就是直接中断程序的执行,用调试器去检查一下程序的情况嘛。于是 F9, F5, F10, F11那么我们就来说说什么是断点,断点是什么?不是 F9 ,也不是那个小红球,在 Intel系列的 CPU(包括 AMD 生产的 CPU)里面,它其实是一个特殊的指令 INT 3。CPU 在执行程序的指令集的时候,只要碰到这个指令,就会中断程序的执行(当然啦,CPU 会通知操作系统,然后然后

3、然后,断点的实现机制我会在以后的文章里面讲解,现在我们就只要知道那个 INT 3 指令会中断程序的执行好吗?)。当然啦,我们需要用事实来证明我上面的话,因此把下面的程序编译并且执行一下,点“Yes”,点“Break” ,对对对,程序中断了,我相信你可以看见的:#include void main()printf(“Before breakpoint“n“);_asmint 3printf(“Before breakpoint“n“);编译方法:1.在开始菜单中打开 Visual Studio 20082005 Command Prompt(Visual Studio 20082005命令行)。

4、2.进入保存上面 C 源代码(int3.c)的文件夹的路径。3.执行编译命令(因为我的机器是 Windows 7 RC + Visual Studio 2008 + x64 CPU,直接编译有一点问题,如果你的机器不是我上面的配置,可以尝试执行cl /Zi int3.c)cl /Zi /c int3.c4.执行链接命令(如果你直接执行了命令 cl /Zi int3.c 的话就可以跳过这一步)。link /libpath:“C:“Program Files“Microsoft SDKs“Windows“v6.0A“Lib“ int3.obj5.运行输出的 int3.exe。这时你应该会看到 Vi

5、sual Studio 弹出来,然后在源代码行的 int 3 上面中断,说明我们已经成功地让 CPU 中断 int3.exe 程序 的执行了。提示:如果你执行 int3.exe 的时候,没有发现 Visual Studio 窗口弹出来的话,那么请点击Visual Studio 菜单项里面的“Tools(工具)”“Options (选项)” ,接着在“Options (选项)”窗口中选择 “Debugging(调试) ”“Just-In-Time(即时调试) ”,然后勾选“Native(原生程序)”选项。如下图所示:“综上所述,断点是 int 3 这个指令触发的!(小时候的数学证明题)”。由 i

6、nt 3 这个指令(当然是在 intel 系列的 CPU 上面)引申出来有哪些函数呢:语言/工具 名称 描述C+ DebugBreak 在 C+代码中硬编码一个断点。C# Debugger.Break 在.NET 代码中硬编码一个断点Visual Studio 断点 设置一个断点Visual Studio 调试之断点进阶篇在上一篇文章 Visual Studio 调试之断点基础篇里面介绍了什么是断点,INT 3 是 Intel系列 CPU 的一个指令,可以让程序产生一个中断或者异常。程序中如果有中断或者异常发生了以后,CPU 会中断程序的执行,去一个叫做 IDT 的部件查找处理这个中断(或者异

7、常)的例程(Handler )。IDT 是操作系统在启动的时候初始化的,至于 IDT 的细节问题,例如什么是 IDT,怎样编写一个 IDT 的例程,怎样 初始化 IDT,可以去网上搜索一些资料。总之,这里我们只要知道,CPU 在执行程序指令过程中,碰到 INT 3 中断程序的执行,CPU 然后去 IDT 表里面找到处理断点的例程入口。这个例程要做的事情就是:1.先看看机器里面是不是安装了一个调试器记住,这一步很重要,之所以重要以后的文章里面会介绍。2.如果机器里面没有安装调试器,那么操作系统就会终止程序的执行。 3.否则操作系统启动调试器,并将调试器附到进程上。4.这样,我们才能在调试器里面检

8、查程序内部变量的值。前面文章里面的 INT 3 (或者 DebugBreak(),或者 Debugger.Break())指令是我们自己在代码里面硬编码进去的,因此我们在 Visual Studio 里,在相应的代码行里面点一下,出现一个小红球,也就是说 Visual Studio 在程序指令集某个地方动态地添加了一个 INT 3指令。现在的问题来了,Visual Studio 是如何在程序中正确找到插入 INT 3 指令的位置的?或者更具体一些,我们在源代码(文本文件)里面设置断点的,Visual Studio 需要把代码行翻译成在程序指令集中的位置。Visual Studio 之所以需要做

9、翻译,是因为通常一行C+或者 C#代码都会对应好几行汇编指令。因此,Visual Studio 需要一个额外的文件来执行这个翻译过程,这个额外的文件叫做调试符号文件(Symbols),是由编译器生成的。Visual Studio 系列的编译器,不论是C#、VB.NET 还是 C+编译器都会生成这个调试符号文件, .pdb 文件。所以如果你花一点时间看看 Debug 文件夹的话,你就会发现这个文件。因此我们来看看 Visual Studio 支持的各种断点,并解释各种断点的实现方式 条件断点 首先我们先看看如何设置条件断点,条件断点有两种,一种是根据触发的次数来设置,另外一种是根据一条预置的条件

10、来设置。 根据触发次数设置比如说,你有一个循环,循环 1000 次,你知道有一个 BUG 总是在 500 次之后才会出现,因此肯定希望在循环内设置一个断点,但是前面 500 次都不会触发这个断点,否则连续按 500 次的 F5 的确不是一件轻松的差事。 根据预置条件来设置如果你已经知道一些条件可能会引发 Bug,那么根据条件来设置则最合适不过了。如下图所示:在“断点条件(Breakpoint Condition)” 对话框里面,只需要输入一条正常的 C#、C+或者 VB.NET 的语句就可以了(当然,语法是根据你项目里面的源代码语法一致),这条语句的要求是必须返回 bool 值否则就不是一个条

11、件了。第三个还有断点过滤器,当你在断点上,右键点击弹出的菜单里面,会有一个“过滤(Filter)”菜单,它允许你限制将断点仅设置在特定的线程上。这里我就不细讲了,有兴趣的话,可以自己写一个多线程或者多进程程序试试这个功能。知道断点的原理以后,理解条件断点应该就不会是问题了。 监视断点(Watching Point) 有的时候,你可能需要查看程序内部一些变量的值,但是你又不希望中断程序的执行。例如你在调试一个网络协议栈,一个程序可能在接收数据包,你想看看数据包的格式,但如果中断程序的执行,会导致后续的数据包丢失。因此,我们一般的做法就是在源代码里面加一些日志记录代码,这样可以将一些变量的值记录下

12、来,以便后续分析。如果日志在产品发布以后还需要的话,在源代码里面加入这些日志代码固然是一个好主意,但是如果你只是想临时看看一些变量的值呢?这个时候,监视断点就很有用了,Visual Studio 的监视断点就可以让你做到在不修改程序源代码的前提下,在调试器窗口中打印一些变量的值。下图演示了监视断点的用法:设置监视断点的步骤,或者说是注意事项吧:1.设置一个普通的断点2.右键单击刚刚设置的断点,在弹出菜单里面选择“When Hit”3.勾选第一个“ 打印一条消息(Print a message)”复选框,输入一串文本,默认情况下,你输入的文本会被直接打印到调试的输出窗口里面来。除了:a.以$符号

13、开头的几个关键字。比如$FUNCTION 就会被替换成断点所在的函数名。其他有一些关键字在“When Breakpoints Is Hit”窗口当中有详细的说明。b.使用 大括号 包含起来的变量名,这样的字符串会被替换成变量的值。这下面就是监视断点的效果,注意,你只能在 Visual Studio 的“输出(Output)”窗口中查看结果。监视断点相对于日志记录的好处是,你不需要改动源代码,并且重新编译代码。实际上 Visual Studio 实现监视断点的原理也很简单,就是插入一个普通的断点,断点触发之后处理并且打印在“When Breakpoints Is Hit”窗口输出的表达式,最后自

14、动恢复程序的执行。Visual Studio 调试之避免单步跟踪调试模式 写完 Visual Studio 调试之断点进阶篇之后,想分享一下我常用的一些调试技巧,后面发现写之前,一些背景知识需要介绍一下。下面是几篇今年 2 月份在 CSDN 写的几篇文章,比如关于如何使用第一次异常处理机会和第二次异常处理机会的区别来快速定位异常发生的位置,如何设置函数断点之类的文章。因为后续我打算写几篇我常用的小技巧,可能需要先了解一些背景知识,就只把链接贴出来了。理解 First Chance 和 Second Chance 避免单步调试 :http:/ http:/ Studio 调试之断点技巧篇 不知道

15、能不能算是技巧啦,写出来放到首页贻笑大方而已。函数断点在前面的文章 Visual Studio 调试之避免单步跟踪调试模式里面我讲了如何设置函数断点,说实话,我个人喜欢设置函数断点,而不是在代码行里面设置断点。一般来说,函数断点在下面几种情形下有用:1. 例如调试一个网站程序,你通过分析网站的日志发现最有可能发生错误的函数,打开调试器并将调试器附加到程序上去,设置函数断点,重新执行网站这样做的好处是,不用到处打开源文件去找出错的源代码行,调试器会自动打开源代码,并且在函数的入口处中断(岂不是很方便?) 。2. 例如你在阅读源代码的时候,通常在读到虚函数调用的时候,因为通常这种调用都是通过基类指

16、针调用的,而你又一时半会不知道到底有哪个继承类的 Overloading 函数会被调用到,函数断点可以告诉你。3. 或者一种特殊的情形,你想读一个程序的源代码,但就是找不到入口 Main 函数,例如.NET 程序,那么直接在 Visual Studio 里面按 F11 就能帮你找到入口函数这是函数断点的一个特殊情形。4. 比如你在调试 Web Service 函数,设置函数断点也是一个快捷的调试方法,这个技巧跟技巧 1 类似。当然,可能有些读者没有办法成功设置函数断点,如果设置函数断点失败,请阅读我的文章“不能设置断点的检查步骤” 。如果里面有一些名词术语(术语请参看文章:调试术语)不知道或者

17、不知道如何设置的话,呃,我会另写一篇文章讲解。断点编程有的时候你可能会碰到这种情况,触发一个断点以后,你发现需要修改一些值,才能使程序继续正确执行下去。例如我以前在中文版本的操作系统上,使用 sscli 里面(调试版)的 csc.exe 编译器编译一些包含语法错误或者语法警告的 C#源文件的时候,csc.exe 总是会莫名其妙地报告内部严重错误,然后就崩溃了。我将调试器附加上去以后,发现是一个 ASSERT 错误,ASSERT(lcid = 0x409),表示 sscli 里面的 csc.exe 总是默认自己在英文操作系统(或者说英文环境)里面运行。而且这一条语句会被执行很多次,手工修改 lc

18、id 的值的确有点麻烦。然后我找源代码找来找去都没有找到 csc.exe 在哪个地方获取到这个 lcid 值(当然我最后找到了,下一个技巧将告诉你我是怎么找到的) ,然而我又不想重启系统(呃也许我就是那种宁愿花 1 个钟头去找节省花费 5 分钟重启系统的方法的那种人) 。这个时候如果调试器可以自动帮你重置 lcid 的值该有多好?幸运的是,Visual Studio 提供了方法让你完成这样的工作。下面是一个简化的代码,因为我一时半会找不到 sscli 了:int lcid = System.Globalization.CultureInfo.CurrentUICulture.LCID;Console.WriteLine(“lcid = 0“, lcid);上面的代码在正常情况下,应该返回当前操作系统语言的 lcid 值,例如英文就是 1033,中文的,呃我忘记了。假设我们现在希望做的是,每当 lcid 的值为 1033 的时候,就自动更正为 0。我们需要:1. 在 Console.WriteLine 这一行上设置一个条件断点,条件断点的设置请参看 Visual Studio 调 试 之 断 点 进 阶 篇 :

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 实用文档资料库 > 策划方案

Copyright © 2018-2021 Wenke99.com All rights reserved

工信部备案号浙ICP备20026746号-2  

公安局备案号:浙公网安备33038302330469号

本站为C2C交文档易平台,即用户上传的文档直接卖给下载用户,本站只是网络服务中间平台,所有原创文档下载所得归上传人所有,若您发现上传作品侵犯了您的权利,请立刻联系网站客服并提供证据,平台将在3个工作日内予以改正。