打印出堆栈指针的值

时间:2013-11-18 22:52:02

标签: c linux stack

如何在Linux(Debian和Ubuntu)的C语言中打印出堆栈指针的当前值?

我试过谷歌但没有找到结果。

7 个答案:

答案 0 :(得分:26)

一个不可移植或甚至保证可以工作的技巧是简单地将本地地址打印出来作为指针。

void print_stack_pointer() {
  void* p = NULL;
  printf("%p", (void*)&p);
}

这实际上会打印出p的地址,这是当前堆栈指针的一个很好的近似值

答案 1 :(得分:18)

没有便携的方法可以做到这一点。

如果您需要gcc / x86的解决方案,可以使用:

register int sp asm ("sp");
printf("%x", sp);

答案 2 :(得分:8)

除了具有duedl0r's answerGCC之外,您还可以使用特定于GCC的__builtin_frame_address(0)(但不是 x86 特定的)。

这也适用于Clang(但有一些bugs关于它。)

获取本地地址(如JaredPar answered)也是一种解决方案。

请注意,AFAIK C标准理论上不需要任何调用堆栈。

请记住Appel的论文:garbage collection can be faster than stack allocation;一个非常奇怪的C实现可以使用这种技术!但AFAIK从未用过C。

人们可以梦想其他技术。而且你可能有split stacks(至少在最近的GCC上),在这种情况下,堆栈指针的概念意义不大(因为那时堆栈不是连续的,并且可能由几个调用的许多段组成)每个框架。)

答案 3 :(得分:5)

Linux上,您可以使用proc伪文件系统来打印堆栈指针。

在/ proc / your-pid / stat伪文件中,在2829字段中查看here

  

startstack%lu                           开头的地址(即底部)                           叠加。

     

kstkesp%lu                           找到的ESP(堆栈指针)的当前值                           在进程的内核堆栈页面中。

你只需要解析这两个值!

答案 4 :(得分:1)

你也可以使用扩展汇编程序指令,例如

Wednesday
Wednesday 
Monday 
Monday 
Monday 
Monday 
Monday 
Wednesday

对于32位系统64必须用32和rsp替换为esp

答案 5 :(得分:1)

您在文件/proc/<your-process-id>/maps中有该信息,与出现字符串[stack]的行相同(因此它独立于编译器或计算机)。这种方法的唯一缺点是,要读取该文件,需要将其设为root。

答案 6 :(得分:1)

尝试lldb或gdb。例如,我们可以在lldb中设置回溯格式。

settings set frame-format "frame #${frame.index}: ${ansi.fg.yellow}${frame.pc}: {pc:${frame.pc},fp:${frame.fp},sp:${frame.sp}}  ${ansi.normal}{ ${module.file.basename}{\`${function.name-with-args}{${frame.no-debug}${function.pc-offset}}}}{ at ${ansi.fg.cyan}${line.file.basename}${ansi.normal}:${ansi.fg.yellow}${line.number}${ansi.normal}{:${ansi.fg.yellow}${line.column}${ansi.normal}}}{${function.is-optimized} [opt]}{${frame.is-artificial} [artificial]}\n"

因此我们可以在调试中打印bp,sp,例如

frame #10: 0x208895c4: pc:0x208895c4,fp:0x01f7d458,sp:0x01f7d414   UIKit`-[UIApplication _handleDelegateCallbacksWithOptions:isSuspended:restoreState:] + 376

进一步了解https://lldb.llvm.org/use/formatting.html