调试术语

原文链接地址:http://blog.csdn.net/Donjuan/article/details/3454597

1.1. 调试模式

调试器可以采用三种模式来调试被调试程序(在下文中,如果没有特别说明的话,简称程序):

  • 一种是直接调试模式,即直接从调试器里面启动程序,就如同我们在Visual Studio里面按下F5就可以调试程序那样。
  • 另外一种是附加(attach)模式,即你可以在程序已经启动的情况下,把你的调试器附加到程序上,进行调试。这种模式通常在调试服务(Service)程序非常有用,例如你的ASP.NET网站可能会存在这样一种bug,在网站运行的过程当中,有一个异常不知道从那个角落里面抛了出来,这时你可以使用附加模式来调试你的网站。
  • 最后一种叫做验尸(post-mortem)调试,这种调试模式允许你调试在客户机器上出错的程序。也就是说,当你的程序发布给客户以后,客户在使用程序的过程中,可能会碰到一些很难重现的错误(bug)。这时操作系统可以将出错的程序的内存保存到一个文件里面,然后你可以在自己的开发机上调试这个文件,找到程序错误的原因。

1.2. 内存文件

1.3. 符号文件

CPU一般都提供一个特殊的指令来实现对断点的支持,因此你在调试器里面设置断点的时候,调试器会在程序的指令流里面插入这个特殊指令。而CPU在执行程序的指令时,如果碰到这个指令,就会自动中断程序的执行,并且将程序的控制权交给调试器,这样你才能通过调试器查看程序里边一些变量的值,以及对程序做一些其他操作。

但问题是,在你设置断点的时候,你只是告诉了调试器要中断执行的代码行,即你只是在源代码文件的某一行点了一下。而通常一行C或者C#代码在编译之后,会被解释成多条机器指令,调试器是怎样将代码行号信息和保存在被调试器里面的机器指令对应起来的呢?

图 1-1 C#源代码与汇编代码的对应关系示例

另外程序中断以后,你在调试器的监视窗口输入了一个变量,调试器显示变量的值,这是最正常的调试场景了。可是调试器是如何知道你输入的变量的类型,又是如何在程序的一堆内存当中,定位到你要查看的变量的值的呢?

其实调试器所做的一系列的魔术,都是和符号文件分不开的。微软的Visual Studio的符号文件以.pdb为后缀名,当你在Visual Studio当中编译好解决方案后,可以在与编译出来的程序的相同文件夹里找到其对应的符号文件,默认情况下,文件名和程序名相同。

符号文件其实是编译器生成的,因此你也可以使用C#的编译器csc为你的程序生成符号文件。Csc程序的/debug开关可以用来控制符号文件的生成:

编译选项

说明

1.4. 符号文件服务器

由于符号文件包含了二进制程序和源代码文件之间的对应关系,因此每次程序升级以后, 你可能会同时有多个版本的程序在不同的客户机上运行。而在调试的时候,手工寻找正确版本的符号文件肯定是一个非常费力的事情。因此就有了符号文件服务器软件的出生,符号文件服务器的工作就是,当你在调试程序的时候,调试器会自动和符号文件服务器交互,获取正确版本的符号文件。

在后面的章节里面,会介绍如何创建一个符号文件服务器,以及如何使用符号文件服务器。

1.5. 工作目录

每一个程序都有工作目录,当你的程序中使用相对路径打开文件的时候,这个相对路径就会和程序的工作目录组成文件的绝对路径,通过这种方式,操作系统才能根据相对路径找到文件。在.NET程序中,你可以使用下面这个属性来获取程序当前的工作路径:

Environment.CurrentDirectory

下面的示例代码演示了如何通过编程手段改变程序的工作目录--为了简介起见,我会在本书的示例代码里面去掉错误处理部分的代码:

using System;

using System.Diagnostics;

using System.IO;

public class StartApp

{

static void Usage()

{

Console.WriteLine("Usage: StartApp <app> <working dir>");

}

static void Main(string[] args)

{

if (args.Length != 2)

{

Usage();

return;

}

ProcessStartInfo si = new ProcessStartInfo(

Path.GetFullPath(args[0]));

// 避免操作系统为运行的程序打开一个新的窗口

si.UseShellExecute = false;

si.WorkingDirectory = Path.GetFullPath(args[1]);

Process.Start(si);

}

}

表 1-1 使用编程方法设置程序的工作目录

时间: 2024-08-04 15:12:09

调试术语的相关文章

理解First Chance和Second Chance避免单步调试

原文链接地址:http://blog.csdn.net/Donjuan/article/details/3859160 在现在C++.Java..Net代码大行其道的时候,很多代码错误(Bug)都是通过异常的形式表现出来的.由于工期紧或者种种原因,很多程序员在碰到程序发生未处理的异常的第一反应就是try - catch (Exception e) { - }.然而代码开发到后期的时候,这种简单粗暴的解决代码错误(Bug)的方式就会在其他不相干的地方表现出来,有的时候甚至导致程序随机的不稳定,而且

Visual Studio调试之断点技巧篇

原文链接地址:http://blog.csdn.net/Donjuan/article/details/4618717 函数断点 在前面的文章Visual Studio调试之避免单步跟踪调试模式里面我讲了如何设置函数断点,说实话,我个人喜欢设置函数断点,而不是在代码行里面设置断点.一般来说,函数断点在下面几种情形下有用: 1. 例如调试一个网站程序,你通过分析网站的日志发现最有可能发生错误的函数,打开调试器并将调试器附加到程序上去,设置函数断点,重新执行网站--这样做的好处是,不用到处打开源文件

.net异常机制

异常机制简介 当CPU运行到一些非法的指令,例如除零错误,访问内存页失败等指令,CPU会生成一个硬件异常,不同的异常有固定的异常代码作为标识符,异常产生以后CPU暂时不能继续执行后续的指令-因为后续的指令有可能也是无效的.当然不能让整个计算机系统就这么当掉,因此CPU内置了一个异常处理表-这个异常处理表只有运行在内核模式的代码才能访问,操作系统在启动的时候初始化这个异常处理表,为每一个异常注册一个异常处理程序,因此这个表看起来就像: 0xC0000005 AccessViolationExcep

OpenStack术语名词及问题调试

从上面你应该也知道我们重启Openstack整个环境方法了吧!一切只因Openstack组件太多,叫复杂; nova baremetal-node-list

OpenStackCLI调试及术语识记

1,Project are organizational units in the cloud,and are also known as tenants or accounts.Each user is a member of one or more projects.Within a project,a user creates and manages instances; qcow2云格式磁盘镜像制作之基于iso制作img格式镜像;

一探前端开发中的JS调试技巧

前言:调试技巧,在任何一项技术研发中都可谓是必不可少的技能.掌握各种调试技巧,必定能在工作中起到事半功倍的效果.譬如,快速定位问题.降低故障概率.帮助分析逻辑错误等等.而在互联网前端开发越来越重要的今天,如何在前端开发中降低开发成本,提升工作效率,掌握前端开发调试技巧尤为重要. 本文将一一讲解各种前端JS调试技巧,也许你已经熟练掌握,那让我们一起来温习,也许有你没见过的方法,不妨一起来学习,也许你尚不知如何调试,赶紧趁此机会填补空白. 骨灰级调试大师Alert 那还是互联网刚刚起步的时代,网页前

VC的常用调试方法

前言 VS是非常强大的IDE,所以掌握VSVC的常用方法,将会使得我们找出问题解决问题事半功倍. 目录 VSVC的常用调试方法 前言 1. Watch窗口查看伪变量 2. 查看指针指向的一序列值 3. 内存泄露查找 4. 调试Release版本 5. 远程调试 6. 函数断点 7. 数据断点. 8. 代码执行时间 9. 格式化数据 10. 格式化内存 Watch窗口查看伪变量 按MSDN的介绍,伪变量就是用来查看特定信息的术语.例如当调用的API失败时,可以用GetLastError获取对应的错

Linux c c++ 开发调试技巧

看到一篇介绍 linux c/c++ 开发调试技巧的文章,感觉挺使用,哪来和大家分享. 通向 UNIX 天堂的 10 个阶梯Author: Arpan Sen, 高级技术人员, Systems Documentation, Inc. (SDI) 讨论几种可以帮助 C++ 开发人员节省时间的技巧和免费工具. C++ 开发人员在日常工作中通常要完成多个任务:开发新软件.调试其他人的代码.制订测试计划.为每个计划开发测试.管理衰退软件(regression suite)等等.在多种角色之间频繁转换会消

软件工程术语(上)

[A] B C D E F G H I J K L M N O P Q R S T U V W X Y Z abstract class 抽象类      提供一组子类共有行为的类,但它本身并不具有实例.抽象类表示一个概念,从中派生的类代表对这一概念的实施. Abstraction 抽象      对视图或模型的创建,其中忽略了不必要的细节,以便专注于一组特定的相关细节. access modifier存取权限      对类.方法或属性进行访问控制的关键字.Java 中的存取权限可以是公有.私