标签:
调试器可以采用三种模式来调试被调试程序(在下文中,如果没有特别说明的话,简称程序):
CPU一般都提供一个特殊的指令来实现对断点的支持,因此你在调试器里面设置断点的时候,调试器会在程序的指令流里面插入这个特殊指令。而CPU在执行程序的指令时,如果碰到这个指令,就会自动中断程序的执行,并且将程序的控制权交给调试器,这样你才能通过调试器查看程序里边一些变量的值,以及对程序做一些其他操作。
但问题是,在你设置断点的时候,你只是告诉了调试器要中断执行的代码行,即你只是在源代码文件的某一行点了一下。而通常一行C或者C#代码在编译之后,会被解释成多条机器指令,调试器是怎样将代码行号信息和保存在被调试器里面的机器指令对应起来的呢?
图 1-1 C#源代码与汇编代码的对应关系示例
另外程序中断以后,你在调试器的监视窗口输入了一个变量,调试器显示变量的值,这是最正常的调试场景了。可是调试器是如何知道你输入的变量的类型,又是如何在程序的一堆内存当中,定位到你要查看的变量的值的呢?
其实调试器所做的一系列的魔术,都是和符号文件分不开的。微软的Visual Studio的符号文件以.pdb为后缀名,当你在Visual Studio当中编译好解决方案后,可以在与编译出来的程序的相同文件夹里找到其对应的符号文件,默认情况下,文件名和程序名相同。
符号文件其实是编译器生成的,因此你也可以使用C#的编译器csc为你的程序生成符号文件。Csc程序的/debug开关可以用来控制符号文件的生成:
编译选项
说明
由于符号文件包含了二进制程序和源代码文件之间的对应关系,因此每次程序升级以后, 你可能会同时有多个版本的程序在不同的客户机上运行。而在调试的时候,手工寻找正确版本的符号文件肯定是一个非常费力的事情。因此就有了符号文件服务器软件的出生,符号文件服务器的工作就是,当你在调试程序的时候,调试器会自动和符号文件服务器交互,获取正确版本的符号文件。
在后面的章节里面,会介绍如何创建一个符号文件服务器,以及如何使用符号文件服务器。
每一个程序都有工作目录,当你的程序中使用相对路径打开文件的时候,这个相对路径就会和程序的工作目录组成文件的绝对路径,通过这种方式,操作系统才能根据相对路径找到文件。在.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 使用编程方法设置程序的工作目录
标签:
原文地址:http://www.cnblogs.com/wuyuan2011woaini/p/5177203.html