一、准备工作
MS引用:在 Visual Studio 调试器(C#、C++、Visual Basic、F#)中指定符号 (.pdb) 和源文件
MS引用:为 C#、ASP.NET 或 Visual Basic 项目 (.NET Framework) 生成符号文件
MS引用:用于控制编译器输出的 C# 编译器选项
1、首先,我们需要一个控制台程序,代码很简单,ConsoleApp1控制台程序在主程序中,调用ClassLibrary1类库中Class1下的Do方法,如下:
2、生成AnyCPU或任意目标平台,代码的目录结构如下:
3、然后在bin/Debug目录下,双击运行控制台程序,按照代码逻辑,程序堆栈会停在“Console.ReadLine();”这一行;
4、(验证正常调试过程.pdb的用处)打开VS,通过“继续但无需代码”进入,选择“调试”-“附加到进程”,输入程序集名称,找到该进程,选择“附加”;
5、附加进程ok后,点击调试的“全部中断”,看到断点停留在了“Console.ReadLine();”这一行:
二、移除.pdb会如何
6、保持程序状态,需要做的是:
①将“..\bin\Debug\ConsoleApp1.pdb”重命名为“ConsoleApp1_Temp.pdb”
②将“..\obj\Debug\ConsoleApp1.pdb”重命名为“ConsoleApp1_Temp.pdb”
(obj下的是源.pdb文件,bin中的是源.pdb文件的副本;同样obj和bin下的exe也是如此;此处可以去了解下编译的过程,是先生成obj下的内容,再将运行时需要的文件拷贝到bin下)
(编译时,.pdb的路径会在被记录在exe程序中,这也是为什么要做②的原因)
7、VS重新进行附加进程,点击“全部中断”,会得到“处于中断模式”的结果,但由于缺少.pdb所以无法定位具堆栈:
三、移除本地代码会如何
7、保持程序状态,恢复在步骤6中所做的,对obj和bin下.pdb的重命名,然后需要做的是:
①将源代码文件“Program.cs”重命名为“Program_Temp.cs”
8、VS重新进行附加进程,点击“全部中断”,会得到“未找到源”的结果,能够在“局部变量”和“调用堆栈”选项卡中看到内容,却没有对应源代码定位:
四、总结
首先,为什么选择附加到进程,而不是在工程中将“活动解决方案平台配置”设置为“Debug”进行启动?
——Debug模式每次启动时,obj下的源.pdb会默认生成,并拷贝到bin输出目录中。
实际上述步骤,更加接近的是在“生产环境下使用.pdb加上源码进行调试”的场景。
五、拓展——Debug和Relase的区别
五-一、正常调试Relase
1、右键“ConsoleApp1”工程-“属性”-“生成”-“高级”;
2、在默认情况下,将“配置”设置为Debug和Relase时,我们能看到的区别在于“优化编码”这一项,Debug时默认“不选中”即“不优化编码”;Release时默认“选中”即“优化编码”。
3、此时,按上述流程同样对Relase下的exe进行调试,会得到提示,并选择“继续调试”:
4、点击“全部中断”,并不会命中当前堆栈“Console.ReadLine();”这一行,且“局部变量”和“调用堆栈”标签页中并无内容。
五-二、取消“优化编码”调试Relase
不再贴图,直接放出结果,如同我们调试Debug一样。
五-三、结论
Debug和Relase在使用VS调试时,主要区别在于是否进行了“优化编码”(实际上即使配置完全一致,对比16进制仍会返现两者不尽相同,比如生成时间戳、代码段地址)。
而优化导致的结果,个人理解就是:
是否能够通过.pdb和源码,在正常的生产环境中,附加到进程并命中断点,即是否支持实时调试。
六、拓展——AnyCPU(首选32位)/x86/x64/ARM的区别
(以下引用MS原文)
PlatformTarget
指定 CLR 的哪个版本可以运行程序集。
XML复制
<PlatformTarget>anycpu</PlatformTarget>
- anycpu(默认值)将程序集编译成可在任意平台上运行。 您的应用程序将尽可能作为 64 位进程运行;当只有 32 位模式可用时,才会回退到 32 位。
- anycpu32bitpreferred 将程序集编译成可在任意平台上运行。 在同时支持 64 位和 32 位应用程序的系统上,您的应用程序将以32 位模式运行。 只能为面向 .NET Framework 4.5 或更高版本的项目指定此选项。
- ARM 将程序集编译成可以在具有高级 RISC 计算机 (ARM) 处理器的计算机上运行。
- ARM64 编译程序集以在由 64 位 CLR 在具有支持 A64 指令集的高级 RISC 计算机 (ARM) 处理器的计算机上运行。
- x64 将程序集编译成可由支持 AMD64 或 EM64T 指令集的计算机上的 64 位 CLR 运行。
- x86 将程序集编译成可由 32 位、x86 可兼容 CLR 运行。
- Itanium 将程序集编译成可由配有 Itanium 处理器的计算机上的 64 位 CLR 运行。
在 64 位 Windows 操作系统上:
- 用 x86 编译的程序集将在 WOW64 下运行的 32 位 CLR 上执行。
- 用 anycpu 编译的 DLL 将在加载它的进程所在的同一 CLR 上执行。
- 用 anycpu 编译的可执行文件将在 64 位 CLR 上执行。
- 用 anycpu32bitpreferred 编译的可执行文件将在 32 位 CLR 上执行。
anycpu32bitpreferred 设置只对可执行文件 (.EXE) 有效,并且需要 .NET Framework 4.5 或更高版本。