为什么我无法调试动态加载的程序集?

时间:2016-11-09 11:04:29

标签: c# .net debugging visual-studio-2015 mef

我正在开发一个Web API项目,该项目使用内部模拟框架,允许拦截和修改来自控制器的响应。它使用MEF加载一个程序集,该程序集包含在匹配某些前置条件时执行的代码。

我知道这个工作正常,因为我可以在响应中看到模拟已经执行,但由于某种原因我无法在动态加载的程序集中调试代码。虽然断点看起来很活跃,但执行永远不会破坏。

The breakpoint is active

我尝试调用Debugger.Break();并确实打破了,但调用堆栈显示为空,Visual Studio只显示此消息:

The application is in break mode

我可以看到程序集及其符号已加载到模块窗口中:

Modules window shows that symbols were loaded correctly

我能够在调用动态加载的程序集(behavior参数)之前中断,如下所示:

private HttpResponseMessage ApplyBehavior(
    IMockBehavior behavior,
    string controller, string action,
    HttpRequestMessage request,
    HttpResponseMessage mockedResponse)
{
    return behavior.Apply(controller, action, request, mockedResponse);
}

如果我尝试在即时窗口中检查behavior变量,Visual Studio将显示以下异常:

behavior.GetType()
'behavior.GetType()' threw an exception of type 'System.IO.FileNotFoundException'
    Data: {System.Collections.ListDictionaryInternal}
    FileName: null
    FusionLog: null
    HResult: -2147024894
    HelpLink: null
    InnerException: null
    Message: "Cannot load assembly 'SuperMam.WebAPI.Mocking'."
    Source: null
    StackTrace: null
    TargetSite: null

这是相当大的应用程序的一部分,我无法提取相关部分。我试图收集尽可能多的信息,但仍然不知道为什么会发生这种情况。

我该怎么做才能解决这个问题?

编辑1

为了确保,如果我从控制器调用代码,我可以正常进入它:

var behaviourType = AppDomain.CurrentDomain.GetAssemblies()
    .First(a => a.FullName.Contains("SuperMam.WebAPI.Mocking"))
    .GetType("SuperMam.WebAPI.Mocking.MyBehaviour");

var behavior = (IMockBehavior)Activator.CreateInstance(behaviourType);
// I can step into this, and view the behaviour variable in the watch
behavior.Apply("dummy", "dummy", Request, null);

但即使我这样做,当模拟框架调用相同的方法时,我也无法进入它。

编辑2

我还注意到,同一个程序集(FullName相同)被加载两次。两个实例之间的区别在于其CodeBaseLocation属性:

  • 其中一个CodeBase等于我的应用程序的bin目录,而Location位置等于C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\...
  • 其中一个的CodeBase等于第一个位置(C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\...),而Location是一个空字符串。

这可能是问题的原因吗?

4 个答案:

答案 0 :(得分:3)

您尝试动态加载的程序集是否在您的系统上编译?

为了调试动态加载的程序集,您需要在DLL旁边有一个PDB文件。该文件包含有关Visual Studio所需的程序集的调试信息。在调试模式下编译程序集时,将在项目的ng-show文件夹中自动创建PDB。如果您已将DLL移动到其他位置,请尝试将PDB移动到同一位置。

答案 1 :(得分:2)

  
    

您的应用已进入中断状态,但当前未执行所选调试引擎支持的代码。

  

我之前也遇到过此错误消息:

https://social.msdn.microsoft.com/Forums/en-US/99b43950-6c82-4945-ba16-04355abf9612/vs2015-breakpoints-dont-work?forum=vsdebug

如果可能,您可以检查它是否与调试选项/设置或VS设置有关。

(1)VS2015的最新更新是更新3。

(2)启用使用托管兼容模式将是此问题的目录。

答案 2 :(得分:2)

原来,原因是MEF没有按照我的想法加载程序集。它是使用Assembly.Load(File.ReadAllBytes(mockDllPath))加载的。由于程序集是从字节数组加载的,因此调试器没有可用的调试信息。

答案 3 :(得分:0)

问题应归因于用于加载装配的方法。

我想你正在使用:

Assembly.LoadFrom ...

尝试使用

Assembly.Load