从符号名和偏移量自动获取源和行号
从前,非托管代码开发人员必须非常努力地将代码偏移量与源文件名和行号关联起来。一种方法涉及为每个模块生成.cod文件(程序集列表),然后费力地将指令偏移量与.cod文件的内容进行比较。
例如,如果从具有客户机接收到错误BatteryMeter!TemperatureAndBatteryUpdaterThread+0xd0,可以返回BatteryMeter.exe的.cod文件,查找TemperatureAndBatteryUpdaterThread的代码列表,然后查找位于(或靠近)偏移量0xd0处的源行。
这个过程可以自动化。前几天有人问我是否还需要使用.cod文件,答案是否定的。如果你启动WinDbg,你只需“文件>打开转储文件”,输入你的.exe或.dll作为转储文件名,然后发出ln命令,如下所示:
0:000> ln BatteryMeter!TemperatureAndBatteryUpdaterThread+0xd0
d:\dev\batterymeter\batterymeterdlg.cpp(58)
如果您手头没有WinDbg又希望自动执行此操作(可能是通过脚本),可以使用DbgHelp API加载相应模块的符号,然后查找符号名称和源信息。所涉及的函数是SymLoadModule64、SymFromName和SymGetLineFromAddr64,生成的程序不超过100行代码:
DWORD displacement;
IMAGEHLP_LINE64 line;
RtlZeroMemory(&line, sizeof(line));
line.SizeOfStruct = sizeof(line);
if (!SymGetLineFromAddr64(hProcess, symbolAddress, &displacement, &line))
{
printf("*** Error retrieving source line for %s: 0x%x\n",
argv[1], GetLastError());
return 1;
}
printf("%s [0x%I64x] = %s line %d (+0x%x)\n", argv[1], symbolAddress,
line.FileName, line.LineNumber, displacement);