从C#调试C dll

我将简要地告诉你情况.

我有一个C#项目,它使用在C中创建的一些DLL.

现在,另外,我还有一个C项目,前一段时间用于创建该DLL.
现在,我想在运行C#项目期间调试C DLL.

我在我的C#项目中启用了“启用非托管代码调试”.

我开始调试C#项目并同时进入一些功能.
一切似乎都没问题.当我到达属于C DLL的函数时,
它询问了C文件的来源,我不得不浏览我的C项目.
(在我认为它抱怨一些.pdb文件之前).

现在,我也设法进入了C函数,但是当我一遍又一遍地说,该函数中的一些数据结构似乎没有填充数据,例如,请参见下面的截图

《从C#调试C dll》

您可以看到blob数据结构为空,DataParser也是如此(它显示内部有0个项目,而在上面的代码中,您可以看到有多个项目被添加到其中).

我真的很感激一些帮助,这里出了什么问题?而我可能在哪里做错了.如何调试此C DLL,以便我还可以看到当前为其变量分配了哪些值?

也许我的调试这个C DLL的方式是错误的?事实上,C#项目正在使用已经创建的DLL,并且我有一个用于创建此DLL的C项目 – 事实上它们是分开的,也许它也必须用它做什么?

PS之前我必须进行更改,如this到C项目和更低的工具集,因为我使用VS2012(奇怪的是如果项目是使用VS2013创建的,因为我认为它是旧项目).该项目还使用了大量手动编写的其他C类.也许这也是问题而且不知何故编译器无法检索它们的值和定义?

在我喜欢的设置中调试C DLL文件的一般步骤是什么?

编辑:PPS.还有一些我见过的有趣事实.例如,如果我在DataParser.Add函数上单击F11(Step into),不一定我被带到该函数的主体,它向我显示了其他函数的主体(可能与它有某种关系).

此外,如果我在第一次调用Request.Add后按F10说,它会跳过多个Request.Add行,例如移到第五行.

EDIT2:在我进入C代码之前,它向我显示警告“源的版本与用于创建DLL的版本不同”.这是一个问题吗?

最佳答案 模块和PDB

模块(.dll / .exe)和调试数据库(.pdb)之间存在链接.此链接是通过两个文件中都存在的时间戳和校验和建立的. Visual Studio会检查这些内容的正确性,否则它会抱怨并且根本不会在断点处停止.

虽然其他调试器(如WinDbg)具有关闭该功能的命令,但Visual Studio没有这样的功能,需要主动操作(例如Chkmatch)才能关闭checmsum验证.只要你没有使用这样的工具,你的调试符号就可以了.

PDB和来源

调试数据库(.pdb)和源之间也有一个链接.此链接由文件名和行号建立.您可以猜测,您的源代码在编译期间不会被修改,因此源代码不包含任何可以验证的校验和或时间戳.

因此,源可能已经改变,并且行号甚至可能不再大致匹配.线号被破坏有几个原因.我有answered a similar question before并列出了行号更改的以下原因,尽管代码本身没有改变:

>代码重新格式化,例如按可见性对方法进行排序,以便移动完整的方法
>代码重新格式化,例如将长行打破80个字符,通常会使事情变得迟钝
>优化使用(R#),删除30行不需要的进口,因此事情向上移动
>插入评论或换行符

如何调试

>如果可以,请恢复该版本的确切源代码.
>完全无源调试,仅通过PDB信息.这样你可以保留二进制组件,如果这很重要(例如,如果一个bug只能用该版本重现)
>重建所有模块以使代码再次与模块匹配.这样你就失去了二进制文件,问题可能无法再复制.

点赞