如何在C程序中打印堆栈的内容?

时间:2012-02-02 19:23:49

标签: c pointers assembly x86

我想,正如标题所说,在我的C程序中打印堆栈的内容。

以下是我采取的步骤:

  • 我做了一个简单的汇编(helper.s)文件,其中包含一个返回我的ebp寄存器地址的函数和一个返回我的esp寄存器地址的函数

    .globl get_esp
    
    get_esp:
        movl %esp, %eax
        ret
    # get_ebp is defined similarly, and included in the .globl section
    
  • 我从我的C程序调用{​​{1}}和get_esp ()函数(get_ebp (),其中fpC是int)
  • 我(成功地,我认为)打印了我的esp和ebp寄存器的地址(fpC = get_esp ();
  • 我尝试了,但未能打印出我的esp寄存器的内容。 (我尝试了fprintf (stderr, "%x", fcP);fprintf (sderr, "%d", *fcP);以及其他方法)。处理此行时,我的程序在运行时遇到分段错误。

我做错了什么?

编辑:这必须通过调用这些汇编函数来获取堆栈指针来完成。 EDIT2:这是家庭作业。

2 个答案:

答案 0 :(得分:5)

如果您使用GNU系统,您可以使用GNU的C库扩展来处理回溯,请参阅here

#include <execinfo.h>

int main(void)
{
     //call-a-lot-of-functions
}

void someReallyDeepFunction(void)
{
    int count;
    void *stack[50]; // can hold 50, adjust appropriately
    char **symbols;

    count = backtrace(stack, 50);
    symbols = backtrace_symbols(stack, count);

    for (int i = 0; i < count; i++)
        puts(symbols[i]);

    free(symbols);
}

答案 1 :(得分:4)

get_esp返回esp,因为它在函数中。但这与调用函数中的esp不同,因为调用操作会更改esp

我建议用一个内联组件替换该功能。这种方式esp在尝试阅读时不会改变。

此外,打印到sderr无济于事。根据我的经验,stderr效果更好。