我正在研究一个调试器,它应该在正在调试的进程的上下文中调用某些函数(例如,kernel32.dll!CreateFileW)时存储当前的堆栈跟踪。
调试器将一些代码注入进程,安装一个钩子。然后钩子使用RtlCaptureStackBackTrace获得堆栈跟踪并将其保存在某处。
然后调试器使用函数SymFromAddr解析每个堆栈跟踪的条目。
它适用于非托管代码。
今天我尝试了这种方法,用于支持CLR的MFC应用程序。现在它是非托管代码。钩子仍然获得堆栈跟踪,但调试器无法解析某些堆栈条目。我猜这些条目属于JIT编译器生成的代码。
我对CLR分析器有点熟悉,可以收到像JITCompilationStarted这样的通知。
问题是如何解决(即获取源文件名和行号)JIT编译器生成的代码的地址?
我不能只调用DoStackSnapshot,因为被挂钩的函数可以被调用很多时间,所以DoStackSnapshot会让这个过程变得懒散。
我可以使用FunctionEnter2 / FunctionLeave,但是当执行进入/离开函数时它们被调用,我无法获得有关确切代码行的信息。
谢谢!
尽管已明确说明,但听起来您的问题归结为从托管分析器中的指令指针获取源位置。
获取模块,元数据标记和IL偏移。
name
参数返回,但是您应该检查pdwModuleFlags
以确保模块存在于磁盘上,否则名称将没有意义(例如,如果模块被发出)。获取文件名和行号。
这是使用symbol store api执行的我建议在监视应用程序或后处理步骤中执行此部分以避免阻止探查器。