我正在使用CLR内存诊断库来获取正在运行的进程中所有线程的堆栈跟踪:
var result = new Dictionary<int, string[]>();
var pid = Process.GetCurrentProcess().Id;
using (var dataTarget = DataTarget.AttachToProcess(pid, 5000, AttachFlag.Passive))
{
string dacLocation = dataTarget.ClrVersions[0].TryGetDacLocation();
var runtime = dataTarget.CreateRuntime(dacLocation); //throws exception
foreach (var t in runtime.Threads)
{
result.Add(
t.ManagedThreadId,
t.StackTrace.Select(f =>
{
if (f.Method != null)
{
return f.Method.Type.Name + "." + f.Method.Name;
}
return null;
}).ToArray()
);
}
}
Run Code Online (Sandbox Code Playgroud)
我从这里得到这个代码,它似乎适用于其他人,但它在指定的行上抛出了一个异常,带有消息This runtime is not initialized and contains no data.
dacLocation 被设为 C:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319\\mscordacwks.dll
Sas*_*ein 10
ClrMD目前不支持.NET 4.6.在GitHub上有一个开放的拉取请求,只用一行修复了这个问题.您当然可以克隆项目并构建自己的ClrMD,但不会出现此问题.
或者,我可以分享我过去几周一直在使用的临时黑客:
public static ClrRuntime CreateRuntimeHack(this DataTarget target, string dacLocation, int major, int minor)
{
string dacFileNoExt = Path.GetFileNameWithoutExtension(dacLocation);
if (dacFileNoExt.Contains("mscordacwks") && major == 4 && minor >= 5)
{
Type dacLibraryType = typeof(DataTarget).Assembly.GetType("Microsoft.Diagnostics.Runtime.DacLibrary");
object dacLibrary = Activator.CreateInstance(dacLibraryType, target, dacLocation);
Type v45RuntimeType = typeof(DataTarget).Assembly.GetType("Microsoft.Diagnostics.Runtime.Desktop.V45Runtime");
object runtime = Activator.CreateInstance(v45RuntimeType, target, dacLibrary);
return (ClrRuntime)runtime;
}
else
{
return target.CreateRuntime(dacLocation);
}
}
Run Code Online (Sandbox Code Playgroud)
我知道,这太可怕了,依赖于反思.但至少它现在有效,你不必更改代码.
小智 6
您可以通过下载Microsoft.Diagnostics.Runtime.dll(v0.8.31-beta)的最新版本来解决此问题:https ://www.nuget.org/packages/Microsoft.Diagnostics.Runtime
v0.8.31-beta版本标记了许多过时的功能,因此正如Alois Kraus提到的那样,它runtime.GetHeap()可能会崩溃。我可以通过如下创建运行时来解决此问题:
DataTarget target = DataTarget.AttachProcess(pid, timeout, mode);
ClrRuntime runtime = target.ClrVersions.First().CreateRuntime();
ClrHeap heap = runtime.GetHeap();
Run Code Online (Sandbox Code Playgroud)
TryGetDacLocation()现在所有的废话都是不必要的。
| 归档时间: |
|
| 查看次数: |
1695 次 |
| 最近记录: |