Tag: backtrace

x86_64调用约定和堆栈帧

我试图理解GCC(4.4.3)为在Ubuntu Linux下运行的x86_64机器生成的可执行代码。 特别是,我不明白代码如何跟踪堆栈帧。 在过去,在32位代码中,我习惯于在几乎所有function中看到这个“序幕”: push %ebp movl %esp, %ebp 然后,在function结束时,也会出现“结局” sub $xx, %esp # Where xx is a number based on GCC’s accounting. pop %ebp ret 或简单地说 leave ret 这完成了同样的事情: 将堆栈指针设置为当前帧的顶部,就在返回地址的正下方 恢复旧的帧指针值。 在64位代码中,正如我通过objdump反汇编看到的那样,许多函数不遵循这个约定 – 它们不会推送%rbp然后将%rsp保存到%rbp,像GDB这样的调试器如何构建回溯? 我真正的目标是尝试找出一个合理的地址,当执行到达程序中的任意函数的开始时,可​​以将堆栈指针向下移动时,将其视为用户堆栈的顶部(最高地址)。 例如,对于“top”,argv的原始地址是理想的 – 但我无法从主要调用的任意函数访问它。 我起初以为我可以使用旧的回溯方法:追踪保存的帧指针值,直到保存的值为0 – 然后,下一个可以算作最高实际值。 (这与获取argv的地址不同,但它会 – 比如说,找出_start或任何_start调用的堆栈指针值[例如__libc_start_main]。)现在,我不知道如何获取64位代码中的等效地址。 谢谢。

gdb奇怪的回溯

我的程序是用dietlibc静态编译的。 它是在ubuntu x64上编译的(使用-m32标志为x86编译)并在centos x86上运行。 编译后的大小只有大约100KB。 我用-ggdb3编译它,没有优化标志。 我的程序使用signal.h来处理SIGSEGV信号,然后调用abort()。 程序运行几天没有问题,但有时会出现段错误。 这是我得到奇怪的回溯,我不明白: username @ ubuntu:〜/ Desktop $ gdb -c core.28569 program-name GNU gdb(GDB)7.2 版权所有(C)2010 Free Software Foundation,Inc。 许可证GPLv3 +:GNU GPL版本3或更高版本 这是免费软件:您可以自由更改并重新分发它。 在法律允许的范围内,不提供任何担保。 输入“显示复制” 和“显示保修”的详细信息。 此GDB配置为“–host = x86_64-linux-gnu –target = i386-linux-gnu”。 有关错误报告说明,请参阅: … 从程序名中读取符号……完成。 [新主题28569] 核心由`program-name’生成。 程序终止,信号6,Aborted。 __kernel_vsyscall()中的#0 0x00914410 设置调试gdb的环境。 函数“internal_error”未定义。 在未来的共享库加载中使断点挂起? (y或[n])[回答N; 输入不是来自终端] 函数“info_command”未定义。 在未来的共享库加载中使断点挂起? (y或[n])[回答N; 输入不是来自终端] .gdbinit:8:源命令文件出错: […]