简体   繁体   English

为什么 dbghelp 无法解析托管调用堆栈中的符号?

[英]why dbghelp cannot resolve symbol from managed callstack?

What's the difference between managed callstack and native callstack, why cannot resolve the symbol from managed callstack by dbghelp?托管调用堆栈和本机调用堆栈有什么区别,为什么 dbghelp 无法从托管调用堆栈中解析符号? can anyone tell me the basic reason?谁能告诉我基本原因?

When a native exe runs, windows maps the exe (and dll's) into memory using memory mapped files functionality (not that that matters).当本机 exe 运行时,windows 使用 memory 映射文件功能将 exe(和 dll)映射到 memory 中(没关系)。 So when your program runs, you have a module address which is the base address that the native exe (or dll) image is loaded from (eg module address points to the first byte in the exe/dll file and so on).因此,当您的程序运行时,您有一个模块地址,它是加载本机 exe(或 dll)映像的基地址(例如,模块地址指向 exe/dll 文件中的第一个字节等)。 So when you have a address from a stack walk, you "know" what module the address is from based on the loaded module list as the address will be in a range one of the modules address ranges.因此,当您从堆栈遍历中获得地址时,您会根据加载的模块列表“知道”该地址来自哪个模块,因为该地址将在模块地址范围之一的范围内。 It then knows the offset into the exe file (ie address - module address == offset into exe).然后它知道 exe 文件的偏移量(即地址 - 模块地址 == exe 的偏移量)。 dbhelp uses this address to find the module and then uses the offset into the exe to find the symbol (the pdb has a table of address ranges to symbols). dbhelp 使用此地址来查找模块,然后使用 exe 中的偏移量来查找符号(pdb 有一个符号地址范围表)。

So this is how it works for a native running code.这就是本机运行代码的工作方式。

Why you can't work for managed exe is because how managed code works.为什么你不能为托管 exe 工作是因为托管代码是如何工作的。

Compiled managed code not native code, it's IL .编译的托管代码不是本机代码,它是IL A managed EXE is a small native wrapper around a IL assembly.托管 EXE 是围绕 IL 程序集的小型本机包装器。 The native wrapper is used to "start" the .net runtime and run the entry point in the IL assembly.本机包装器用于“启动” .net 运行时并运行 IL 程序集中的入口点。

The .net runtime uses JIT to convert the IL to native code. .net 运行时使用JIT将 IL 转换为本机代码。 It does this by allocating memory, generating the native code and marking the memory page as excutable, then jumping to it.它通过分配 memory、生成本机代码并将 memory 页面标记为可执行文件,然后跳转到它来做到这一点。 So when these addresses show up in a stack walk, it's doesn't map to ANY loaded native module (as it doesn't).因此,当这些地址出现在堆栈遍历中时,它不会 map 到任何加载的本机模块(因为它没有)。 So you just see a address it can't map to any PDB file.所以你只看到一个地址它不能 map 到任何 PDB 文件。

So to be able to map this unknown addresses to a managed symbol, you need to have:因此,为了能够将 map 这个未知地址分配给托管符号,您需要:

  • internal knowledge of how the managed runtime works托管运行时如何工作的内部知识
  • access to memory of the process to be able to lookup it's internal runtime tables to resolve these unknown addresses to a managed symbol (this is the reason why you need a full memory dump it resvole .net stacks)访问进程的 memory 以便能够查找其内部运行时表以将这些未知地址解析为托管符号(这就是为什么您需要完整的 memory 转储它转储 Z2D50972FCECD37061295145507F)

So dbghelp is only for native symbol mapping and knows nothing about managed stack traces.所以 dbghelp 仅用于本机符号映射,对托管堆栈跟踪一无所知。

The managed stack traces of memory dumps (or live process memory) needs knowage / access to the internal managed runtime tables to be able to resolve the temporary executable memory pages to managed symbols. memory 转储(或实时进程内存)的托管堆栈跟踪需要了解/访问内部托管运行时表,以便能够将临时可执行文件 memory 页面解析为托管符号。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM