C#调试含有源代码的动态链接库遇见there is no source code available for the current location提示时的解决方案
C#调试含有源代码的动态链接库遇见there is no source code available for the current location提示时的解决方案:
1.首先试最常规的方法:Clean and then rebuild solution,但是没有解决
2.进入Tools>Options,选择Debugging>General 却掉 Enable address-level debugging 选项,在去掉 Require source files to exactly match the original version.
Okay,解决问题。
最近在维护一个项目的时候有这样一个问题,项目Solution A引用了第三方的DLL文件,而我现在需要使用DLL类库的一些工具类,但是又没有相关的文档,所以我就需要Debug到DLL中进行调试查看代码的逻辑。开始的时候我想通过.NET Reflector反射出源代码,但是因为一些原因此方法行不通。现在我找到了遗留下来的DLL的源码,但是在另外的一个solution B中,所以现在我想要调试这些源码,要做的就是把源码映射到我们这个项目的DLL中。在介绍方法之前,先简单的说几个概念。PDB文件,DLL文件,源代码CS文件。当我们想调试一个DLL文件的时候,这三者是一个都不能少的。
DLL文件
就是程序在执行的时候,要使用的文件。注意,程序在运行的时候使用的是DLL这种二进制文件,而不是我们自己写的代码,是我们写的代码通过编译出来的DLL文件。
CS源代码
这就是编写的代码,用来生成DLL文件。程序在运行的时候,是根本不需要CS文件的。
PDB文件
当你编译一个project的时候,在bin目录下,伴随着DLL文件,你都会看到一个PDB文件,这个文件是做什么的呢。PDB是Program Database的简称,也成为Symbol File.PDB中存储的信息用来映射.cs文件中的源代码与编译后的DLL文件的对应关系。Debugger,即调试器,会使用这些信息来解析出两方面的信息:在Visual Studio中的呈现出来的源代码中的行号和这一行在DLL中的地址,即当在Visual Studio中的源代码中的某一行设置一个断点后,因为调试时运行的是DLL文件,Debugger需要知道中断在DLL中的某个地方,而PDB中正是记录着行号与这个地址的对应关系。PDB中解析出来的另一个信息是,这个DLL的源代码在哪里。当然如果是自己写的代码,源代码就在project下。但是如果我们引用了第三方的框架,比如说ASP.NET Framework,这时候我们本地根本就没有源代码,这时候PDB中记录了远端server上的代码地址。一句话概括,PDB文件充当了一个DLL与CS源代码之间的桥梁。
现在我们设定一种需求,比如说,我现在想在我的MVC Project中调试ASP.NET MVC Framework中诸如MVCHandler的Process Request方法,现在我们没有源代码,我们没有办法设置断点,即使使用F11 Step By Step调试,到了这种没有源码的代码行的时候,也是会直接跳过的,因为根本就没有地方可去啊。在调试的时候有一种My Code的概念,只有My Code的DLL才可以调试。其实,说白了,My Code的DLL就是有PDB的DLL。我们要调试MVC的DLL,首先就要获取System.web.mvc对应的PDB文件。在Project的调试状态下,点击Debug-->Windows-->Module,会发现System.web.mvc dll是 Cannot find or open the PDB file状态。微软有专门的服务器来提供框架的代码,所以我们可以从服务器上获取pdb文件。然后在Module中右击System.web.mvc一行,选中load pdb from server,会发现PDB会从server中load到本地。如果此时调试MVC代码,会有下图一样的提示。
因为此时Debugger认为你有PDB文件,是My Code,尝试着去调试,但是没有源代码,所以会提示你映射源代码。我们现在需要设置Tools-->Options-->Debugging-->Genral-->Enable Source Server为选中状态,这样,当调试System.web.mvc的时候,会自动从服务器下载源代码到本地。这时候,就可以调试诸如MVCHandler等ASP.NET MVC Framework中的类了。
回到我们最开始的需求,我们现在的情况是,我们的第三方DLL没有可以下载PDB文件的服务器。所以,我们要把源代码solution B中的DLL在build的时候,生成的PDB文件,拷贝到Soution A中,并且在Debug模式下,Moudule中指定第三方DLL的对应PDB的地址。这时候,在调试的时候,Debugger发现这个DLL中没有标记源代码服务器地址,会向上文说到的一样,会提示问你源代码在哪里,这时候你把路径映射到你本地的源代码就可以了。
注意:在第一种情况下,获取System.web.mvc的pdb文件的时候,是Visual Studio根据DLL中的相关信息,向微软的特定的server发出针对于某个pdb文件的请求,并下载的本地。这个过程是很精确的,下载的版本都是一致的,因为dll中都有相关信息记录的。而在第二种情况下,没有sever可供下载,需要人为导入。这个过程需要非常准确,就是说,你solution A中引用的DLL,必须跟你自己导入的PDB完全一致,完全对应,必须是产生DLL的同时产生的PDB.VS编译器有这样一种机制,在编译C#代码并产生PDB的时候,会有一种算法来优化PDB,好像还涉及到时间戳什么的,就是说,即使先后代码完全一致没有变动,在先后两次编译产生的PDB也是不一样的,如果在调试的时候导入的不一致,是不会映射成功的。
引文链接:
there is no source code available for the current location 解决方案
C#调试含有源代码的动态链接库遇见there is no source code available for the current location提示时的解决方案的更多相关文章
- 在ASP.NET 5项目中使用和调试外部源代码包
(此文章同时发表在本人微信公众号"dotNET每日精华文章",欢迎右边二维码来关注.) 题记:由于在ASP.NET 5中,项目依赖都是通过"包"来引用,所以使用 ...
- 调试EF源代码环境配置
下载EF6的源代码,运行build编译,Nuget会自动下载所需的DLL. 打开EF的工程,可以在EF解决方案下直接新建调试用的项目代码 添加EF引用时选择解决方案中的Entity Framework ...
- 调试 ms 源代码
如果需要调试 WPF 源代码或框架源代码,那么需要使用 DotPeek. 首先需要下载 dotPeek ,可以到官网下载 dotPeek: Free .NET Decompiler & Ass ...
- 调试Java源代码时变量的值无法追踪怎么办?
问题:调试Java源代码时,只能看到源代码,却无法查看源代码中的变量的即时值 原因:jre为了节省空间,在打包时去掉了class文件中的调试信息. 思路:使用jdk里的src.zip源码重新编译生成完 ...
- 调试 Hadoop 源代码
环境是 64bit Ubuntu 14.04 系统, jdk 1.7 以及 Eclipse Mars (4.5) 这里介绍两种调试 Hadoop 源代码的方法: 利用 Eclipse 远程调试工具和打 ...
- 常量,字段,构造方法 调试 ms 源代码 一个C#二维码图片识别的Demo 近期ASP.NET问题汇总及对应的解决办法 c# chart控件柱状图,改变柱子宽度 使用C#创建Windows服务 C#服务端判断客户端socket是否已断开的方法 线程 线程池 Task .NET 单元测试的利剑——模拟框架Moq
常量,字段,构造方法 常量 1.什么是常量 常量是值从不变化的符号,在编译之前值就必须确定.编译后,常量值会保存到程序集元数据中.所以,常量必须是编译器识别的基元类型的常量,如:Boolean ...
- 调试JDK源代码-一步一步看HashMap怎么Hash和扩容
调试JDK源代码-一步一步看HashMap怎么Hash和扩容 调试JDK源代码-ConcurrentHashMap实现原理 调试JDK源代码-HashSet实现原理 调试JDK源代码-调试JDK源代码 ...
- 调试HotSpot源代码
之前的文章在Ubuntu 16.04上编译OpenJDK8的源代码 已经介绍过在Ubuntu上编译OpenJDK8的源代码,这一篇将介绍在Ubuntu上调试OpenJDK8源代码的2种方式. 1.GD ...
- 调试HotSpot源代码(配视频)
本文将详细介绍在Ubuntu16.04 LTS上对OpenJDK8进行编译,为了方便大家快速搭建起OpenJDK8的调试开发环境,我还录制了对应的视频放到了B站上,大家可以参考. 视频地址:https ...
随机推荐
- vue-router 实现导航守卫(路由卫士)
路由跳转前做一些验证,比如登录验证,是网站中的普遍需求. 对此,vue-route 提供的 beforeRouteUpdate 可以方便地实现导航守卫(navigation-guards). 导航守卫 ...
- 详解php常量const与define的区别和实例
所谓常量是一个简单的标识符.在脚本执行期间该值不能改变.常量默认大小写敏感.通常常量标识符总是大写的.常量只能包含标量数据(boolean.integer.float和string).可以定义reso ...
- XHTML和HTML有什么区别
HTML与XHTML之间的差别,主要分为功能上的差别和书写习惯的差别两方面. 关于功能上的差别,主要是XHTML可兼容各大浏览器.手机以及PDA,并且浏览器也能快速正确地编译网页. 由于XHTML的语 ...
- io流中read方法使用不当导致运行异常的一点
public class CopyMp3test { public static void main(String[] args) throws IOException { FileInputStre ...
- android IO流操作文件(存储和读取)
存储文件: public class FileOperate extends Activity { private static final String FILENAME = "mydat ...
- ORACLE 导出表结构及备注
https://blog.csdn.net/u013303551/article/details/52354230 SELECT t.table_name, t.colUMN_NAME, ...
- PSP软件开发过程
1. 引言 这是为了编写psp系统的软件需求分析,主要按照提供的相关需求和功能. 1.1 项目风险 风险承担者包括: 任务提出者:承担任务不能完全按照想象的做出,投入等: 软件开发者:可能不能按时交付 ...
- Invalid argument during startup: unknown conf file parameter : requirepass
redis 设置来密码,出现来这个错误, 把配置文件那一行的 空格 去掉 # requirepass foobared 改成 requirepass 123456 因为# 和 requirepass ...
- MySQL 5.7 Reference Manual】15.4.2 Change Buffer(变更缓冲)
15.4.2 Change Buffer(变更缓冲) The change buffer is a special data structure that caches changes to se ...
- 用Model来计算cell的高度
用Model来计算cell的高度 效果: 将计算cell高度的方法直接移植到Model当中,初始化的瞬间就计算好了高度,非常好用! 源码: Model // // Model.h // // Copy ...