从图像RVA获取方法名称



我想从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不是最适合这个任务的。

最新更新