我想从ETL文件(Windows的事件跟踪)导出堆栈跟踪数据到一个更可读的格式。
CPU分析数据只对方法名有用,但是当在记录机器上没有符号服务器访问存在时,记录数据量将有用,以便稍后将方法名加载到工具中,作为额外的后处理步骤。
输入将是例如带有RVA(相对虚拟地址)的dll,如
kernel32.dll + 0 xdddd
在存储这些数据之后,我想从中获得完整的方法名称。据我所知,服务器查找只使用元组
- Pdb Guid
- Pdb年龄 <
- Pdb名称/gh>
理论上,我应该能够使用带有以下签名的辅助方法检索方法名:
string GetMethod(string dll, long RVA, Guid pdbGuid, int pdbAge, string pdbName)
查找方法的正常方法是使用Dbghelp.dll。为了能够使用,我需要调用syminialize,但所有这些api都需要一个进程句柄。
BOOL IMAGEAPI SymInitializeW(
[in] HANDLE hProcess,
[in, optional] PCWSTR UserSearchPath,
[in] BOOL fInvadeProcess
);
当输入不是活动进程或内存转储文件时,是否有人有从Image RVA地址获取方法名称的经验?或者我需要使用另一个库(例如msdia140.dll)?
PerfView已经完全支持这个功能。https://github.com/microsoft/perfview/blob/main/src/TraceEvent/Symbols/NativeSymbolModule.cs
/// <summary>
/// This overload of SourceLocationForRva like the one that takes only an RVA will return a source location
/// if it can. However this version has additional support for NGEN images. In the case of NGEN images
/// for .NET V4.6.1 or later), the NGEN images can't convert all the way back to a source location, but they
/// can convert the RVA back to IL artifacts (ilAssemblyName, methodMetadataToken, iloffset). THese can then
/// be used to look up the source line using the IL PDB.
///
/// Thus if the return value from this is null, check to see if the ilAssemblyName is non-null, and if not
/// you can look up the source location using that information.
/// </summary>
public SourceLocation SourceLocationForRva(uint rva, out string ilAssemblyName, out uint methodMetadataToken, out int ilOffset)
{
这正是我需要的,它使用msdia140.dll。它看起来像"正常的"。Dbghelp.dll不是最适合这个任务的。