在运行时从另一个 AppDomain 调试动态加载的 DLL

Posted

技术标签:

【中文标题】在运行时从另一个 AppDomain 调试动态加载的 DLL【英文标题】:Debugging a dynamically-loaded DLL from another AppDomain at Runtime 【发布时间】:2011-02-04 09:55:57 【问题描述】:

好的,在解决了如何在运行时在正在运行的应用程序中热加载 DLL 之后(请参阅我的 previous post),我注意到在新加载的 DLL 中插入的断点没有被命中。

情况 我有一个服务器应用程序,我希望避免在每次更改动态加载的 DLL(通过反射)时终止/重新运行

目标 这是我正在尝试做的事情(我知道这本身可能是不可能的):

运行 Application.exe 在newAppDomain中加载Process.dll并运行Process 调试Process.dll 卸载Process.dll 编辑进程代码,重新编译Process.dllApplication.exe 中动态地重新加载它 调试Process.dll 等等……

问题 我注意到,当 Application.exe 在调试模式下启动时,附加到 Application.exe 的调试器无法访问从另一个 AppDomain 加载的代码 (我想如果我只是直接从可执行文件启动 Application.exe,就无法让 VS 调试器调试任何东西,包括新加载的 DLL)

可能的解决方法 一种解决方法(丑陋)的解决方案是将 DLL 的“注入”分离到正在运行的应用程序中的单独可执行文件中,然后可由 VS 调试器监控

我必须承认我有点困惑。 有什么高效、干净的想法吗?

【问题讨论】:

这很奇怪。我有一个将应用程序加载到辅助应用程序域的应用程序服务器,并且设置断点没有问题。 Process.dll 文件是您用来启动 Application.exe 的解决方案的类项目的输出吗? 在您引用的问题中听起来您还没有解决卸载程序集的问题。在这种情况下,您的代码不会中断,因为调试符号不匹配。 可能是您的应用程序加载 dll 的位置不是在调试模式下构建 dll 的位置 【参考方案1】:

由于它可能对其他人有所帮助(因为这对我来说是一个热门搜索结果),我发现添加对“其他”项目的 DLL 的引用可以调试正在“注入”的程序集。虽然我不会像这样部署我的解决方案,但它确实允许我至少调试注入的代码以解决其他稳定代码的问题。这表明 IDE 在确定程序集标识(或类似标识)时会查看引用。

在这种情况下,DebugBreak() 什么都不做,如果没有添加引用,VS 调试器将不会收到信号。我没有测试,但可以想象任何其他调试器都可以正常发出信号,所以这再次表明 IDE 明确忽略了信号(其他 DebugBreak()s 工作正常。)

作为一名资深的 .NET 开发人员,我不得不说这个问题对我来说是新问题,即。我敢肯定,如果我们加载 Windows 2000、VS.NET 2001-2002 和相同的测试代码,中断信号就很好。

根据 OP 之前的帖子,很可能正在加载的程序集实际上是以不同的身份加载的,即使它是同一个程序集但从不同的位置/机制(例如)加载,CLR 会将其识别为一个独特的程序集,因此 IDE 也将如此。

在某些情况下,有些读者可能会也可能不会发现 LoaderOptimization 有价值,他们在 appdomains 之间加载相同的程序集并注意到同一个程序集被多次加载。

某人,我被难住了大约一个小时。谢谢。

【讨论】:

感谢您的洞察力。有趣的解决方案。【参考方案2】:

是否将System.Diagnostics.Debugger.Break() 放入您当前有断点的DLL 中,是否正确地抛出了中断?

http://msdn.microsoft.com/en-us/library/system.diagnostics.debugger.break.aspx

如果不是,我倾向于同意 Sam,卸载失败,或者您加载的库与您想象的不同。

【讨论】:

以上是关于在运行时从另一个 AppDomain 调试动态加载的 DLL的主要内容,如果未能解决你的问题,请参考以下文章

从另一个 WPF 应用程序加载 WPF 应用程序程序集,出现错误:无法在同一个 AppDomain 中创建多个 System.Windows.Application 实例

C# 通过 AppDomain 应用程序域实现程序集动态卸载或加载

C# 通过 AppDomain 应用程序域实现程序集动态卸载或加载

是否可以在运行时从 Android 应用程序动态加载库?

C# - 从另一个 AppDomain 中的方法返回值

是否可以从另一个单独的 .NET AppDomain 更改 .NET AppDomain 中的字符串属性的值