我正在对一个在 Windows 上运行但在 Wine[1] 上进入无限循环的 64 位 .NET 应用程序进行功能测试。我已经根据我是否注释了看似微不足道的代码行(它不是控制流行)来隔离使循环发生的条件,但是由于该行似乎微不足道,因此对我来说毫无意义,所以我没有想法如何为它制作一个 MCVE。因此,我试图弄清楚 Wine 上实际循环的内容。我使用的是官方 .NET 框架,而不是 Mono,因为我的应用程序使用混合模式 C++/CLI DLL。
我想到了 2 个选项来调试这个无限循环:
- 获取附加到 Wine 的 .NET 调试器。我以前在这个兔子洞里呆了好几天,但从来没有找到解决办法。
- 在程序开始无限循环后打印所有 CLR 线程(使用后台线程)的堆栈跟踪。
对于#2,我尝试过:
using (DataTarget target = DataTarget.CreateSnapshotAndAttach(Process.GetCurrentProcess().Id))
{
ClrRuntime runtime = target.ClrVersions.First().CreateRuntime();
foreach (ClrThread thread in runtime.Threads)
{
var stackFrames = thread.EnumerateStackTrace();
Console.WriteLine($"Thread {thread.ManagedThreadId}");
foreach (var frame in stackFrames)
Console.Error.WriteLine(frame);
}
}
但是在 Wine 上,这给了我:
System.EntryPointNotFoundException: Unable to find an entry point named 'PssCaptureSnapshot' in DLL 'kernel32.dll'.
所以事实证明 PssCaptureSnapshot 是一个太新的功能,Wine 不支持。
没有 PssCaptureSnapshot 的解决方法可能是执行应用程序转储并离线加载,但我不知道如何在 Wine 中执行此操作。
[1] 实际上我只在最近的 Wine 版本上得到这个无限循环。特别是 Wine 7 稳定和分期。我为修复另一个问题而升级的版本 3.1.2-devel 没有这个无限循环问题。