在Windows上,如果一个模块没有涉及一个模块的符号,比如崩溃转储,那么在callstack中该模块下面的所有调用都是错误的(不仅错过了名称,还有序列)
在Linux或Mac OS X上,如果没有符号,则不会显示功能名称,但仍会保留呼叫顺序。
callstack展开或符号生成的机制有何不同导致这种差异?
答案 0 :(得分:2)
在Windows中,仍然可以为没有符号信息的应用程序获取完整的调用堆栈,前提是“堆栈帧指针”放在调用堆栈上。如果使用debug进行编译,则这些堆栈帧指针由Visual Studio编译器生成,但如果使用优化(/ Ox)进行编译则不会生成。因此,如果您仍然希望堆栈帧指针具有优化,则必须添加/ Oy-编译器选项(Oy-代表:不要删除堆栈帧指针)。
堆栈帧指针只是指向下一个堆栈帧。因此,调试器和崩溃处理程序可以轻松获取堆栈(通过查看堆栈框架指针以跟随堆栈,并使用堆栈上的返回地址)。
如果应用程序没有堆栈帧指针,则调试器或崩溃处理程序必须使用调试信息来了解函数参数的数量,局部变量的数量,...以获取每个堆栈的大小框架并跟随调用堆栈上的所有堆栈帧。