事实上gcc的所有级别的优化(-O, -O2, -O3等)都会打开-fomit-frame-pointer,该选项的功能是函数调用时不保存frame指针,在ARM上就是fp,故我们无法按照APCS中的约定来回溯调用栈。但是GDB中仍然可以使用bt命令看到调用栈,为什么?得知GDB v6之后都是支持DWARF2的,也就意味着它可以不依赖fp来回溯调用栈(详见http://gcc.gnu.org/ml/gcc/2003-10/msg00322.html)。
看来想在代码中动态显示调用栈而又不希望使用GDB的朋友,只能在编译时关掉-fomit-frame-pointer了。