打印出堆栈指针的值

Jui*_*icy 17 c linux stack

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

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

Jar*_*Par 32

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

void print_stack_pointer() {
  void* p = NULL;
  printf("%p", (void*)&p);
}
Run Code Online (Sandbox Code Playgroud)

这将基本上打印出其地址p是当前堆栈指针的良好近似值

  • 没有必要初始化`p`,因为它的值永远不会被使用 - 也没有任何特别的理由让`p`成为`void*`(它可能也是一个`int`).`void*`值的正确格式是`%p`,而不是'%d` - 你需要将指针值转换为`void*`.所以:`int dummy; printf("%p \n",(void*)&dummy);`.(你也拼错了`printf`.)但是,这似乎给出了当前堆栈指针的合理近似值. (6认同)
  • @KeithThompson我意识到`NULL` init是不必要的,但我也不能强迫自己编写使用uninitialize变量的代码.比打印堆栈指针感觉更脏:) (3认同)
  • @JaredPar:使用未初始化的变量,您可以做很多事情,例如为它赋值。仅使用其* value *会引起问题。 (2认同)
  • @KeithThompson是的,我知道未初始化的价值观是如何运作的 (2认同)

due*_*l0r 21

没有可移植的方法来做到这一点.

如果你想要一个gcc/x86的解决方案,你可以使用这个:

// broken with clang, but usually works with GCC
register void *sp asm ("sp");
printf("%p", sp);
Run Code Online (Sandbox Code Playgroud)


Bas*_*tch 9

除了duedl0r特别是GCC的答案之外,你可以使用__builtin_frame_address(0)GCC特定的(但不是x86特定的).

这也适用于Clang(但有一些错误).

获取本地地址(如JaredPar回答)也是一种解决方案.

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

记住Appel的论文:垃圾收集比堆栈分配更快 ; 一个非常奇怪的C实现可以使用这种技术!但AFAIK它从未被用于C.

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


Pas*_*lis 5

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

看看这里,以在/ proc /你-PID / STAT伪文件,在田野2829

startstack%lu 堆栈开始(即底部)的地址。

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

您只需要解析这两个值!