You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

backtrace()栈回溯偏移1行:main函数栈帧定位异常

栈回溯中main函数栈帧定位偏移的原因

你遇到的问题核心是函数调用的返回地址机制导致的:当CPU执行call old_backtrace指令时,会自动把下一条指令的地址压入栈中,作为函数返回后要执行的位置。backtrace获取到的栈帧地址正是这个返回地址,而非调用指令call本身的地址。

具体场景拆解

你的main函数里,调用old_backtrace()的行之后是char* foo;的定义(对应代码第25行)。编译后,call old_backtrace的下一条指令就对应这一行的内存位置,所以backtrace给出的main+0x18实际是这个返回地址。用addr2line解析时,这个地址会映射到它所在的代码行(第25行),而非调用old_backtrace()的行。

而你把地址减1后,就指向了call old_backtrace指令所在的内存位置,自然就能正确定位到调用点的代码行。

补充说明

  • 这个行为是x86_64架构和System V ABI的固有机制,和编译优化级别(你用的-O0)无关。
  • old_backtrace()的地址定位准确,是因为backtrace捕获的是进入该函数后的栈帧起点,对应函数内执行的第一条指令位置,和函数调用的返回地址机制不冲突。

你的代码示例

#include <execinfo.h>
#include <stdlib.h>
#include <stdio.h>

void old_backtrace()
{
    int m_maxNumFrames = 30;
    void** m_frames = (void**)malloc(m_maxNumFrames * sizeof(void*));
    int m_numFrames = backtrace(m_frames, m_maxNumFrames);

    char** strs = backtrace_symbols(m_frames, m_numFrames);

    printf("Call stack:\n");
    for (int i = 0; i < m_numFrames; ++i) {
        printf("%s\n", strs[i]);
    }
}

int main(int argn, char** argc) {

    old_backtrace();

    char* foo;

}

编译命令

gcc -g3 -rdynamic -O0 test.cpp -o output

栈回溯输出

./output(_Z13old_backtracev+0x39) [0x555fc6b201e2]
./output(main+0x18) [0x555fc6b20259]
/lib/x86_64-linux-gnu/libc.so.6(+0x29d90) [0x7f27645f9d90]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0x80) [0x7f27645f9e40]
./output(_start+0x25) [0x555fc6b200e5]

内容的提问来源于stack exchange,提问作者Steve

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 01:23:35