堆栈展开在调用栈和程序执行中定义。
堆栈展开可能由于多种原因而失败:
如果堆栈已被用户代码破坏;如果是这样,则程序可能进行核心转储,或者数据收集代码可能进行核心转储,具体取决于堆栈被破坏的确切方式。
如果用户代码不遵循函数调用的标准 ABI 约定。特别是,在 SPARC 平台上,如果在执行保存指令之前更改了返回寄存器 %o7。
在任何平台上,手工编写的汇编程序代码都可能违反约定。
如果在从堆栈中弹出被调用方的帧之后,但在函数返回之前,叶 PC 位于函数中。
如果调用栈包含的帧超过 250 个,则收集器没有用于完全展开调用栈的空间。在这种情况下,调用栈中从 _start 到某个点的函数的 PC 不会记录在实验中。人工函数 <Truncated-stack> 显示为从 <Total> 调用,以清点所记录的最上面的帧。
如果收集器无法在 x86 平台上展开优化的函数的帧。
如果使用 -E 或 -P 编译器选项生成中间文件,则分析器将中间文件用于带注释的源代码,而不是原始源文件。使用 -E 生成的 #line 指令可能会导致为源代码行分配度量时出现问题。
如果函数中的指令没有行号(这些行号引用为生成该函数而编译的源文件),则带注释的源代码中会出现以下行:
function_name -- <instructions without line numbers>
在以下情况下可能缺少行号:
编译时未指定 -g 选项。
调试信息在编译后被剥离,或者包含该信息的可执行文件或目标文件被移动或删除或者随后被修改。
函数包含从 #include 文件而不是从原始源文件生成的代码。
在进行较高级别优化时,如果代码从不同文件中的函数内联。
源文件具有引用某个其他文件的 #line 指令;使用 -E 选项进行编译,然后再编译生成的 .i 文件是出现此情况的一种方式。使用 -P 标志编译时也可能会出现此情况。
找不到读取行号信息的目标文件。
所用的编译器生成不完整的行号表。