【问题标题】:What are the exact contents of a program stack in C?C中程序堆栈的确切内容是什么?
【发布时间】:2011-03-06 15:25:06
【问题描述】:

我想知道程序堆栈的确切内容。

分支操作是如何完成的?

使用 gdb 调试程序时内存转储是什么意思?

是否给程序栈?

TIA, 普拉文

【问题讨论】:

    标签: c gdb stack


    【解决方案1】:

    C 语言本身并不强制要求使用堆栈 - 它定义行为而不是实现。

    但是,在常见的情况下,程序堆栈用于存储几个东西:

    • auto 存储持续时间声明的对象(即普通、非static 局部变量);
    • 功能参数;
    • 返回地址(代码中在return; 或到达当前函数末尾后应恢复执行的位置);
    • 非标准alloca()函数分配的内存;
    • 编译器所需的临时值,例如保存的寄存器内容、alloca() 的内务管理信息、可变长度数组的大小和计算中使用的中间值。

    这不是一个详尽的列表 - 其他更奇特的东西,如 Trampolines 有时也存储在堆栈中。一般情况下,它是当前函数返回调用者后不再需要的工作项的临时存储区域。

    调试器中的“回溯”显示堆栈的部分(但不是全部)内容。

    【讨论】:

      【解决方案2】:

      堆栈是一个内存区域,包含子程序参数、局部变量和子程序的返回地址。

      在包括英特尔在内的许多架构上,堆栈从上到下增长 - 这意味着每次将数据推送到堆栈时堆栈指针都会递减。

      典型的函数调用序列如下所示:

      • 推送论据
      • 跳转到子程序(将返回地址压入堆栈)
      • 在某些语言中(例如 Pascal),基指针被压入堆栈。
      • 被调用的子例程在堆栈上为其局部变量分配空间。

      为了生成堆栈跟踪,运行时环境只需扫描堆栈以确定返回地址指向的位置。我写了“简单”,但如果没有将基指针保存到堆栈中,情况就不那么简单了,因为可能无法确定除当前堆栈帧之外的任何堆栈帧的位置。

      【讨论】:

        【解决方案3】:

        请参阅下面的链接,它可以为您提供更好的想法 Variables and Memory

        它在内存损坏发生之前提供堆栈跟踪。堆栈跟踪是与传递的参数一起进行的一系列函数调用。

        【讨论】:

        • 我认为内存转储与核心转储不同。还有程序堆栈的内容是什么?假设我对函数进行了 3 次递归调用,该函数有 2 个局部变量、2 个静态变量、2 个动态分配的指针和 2 个全局变量。
        • @Praveen 静态变量不是堆栈帧的一部分,动态分配的指针在堆上,函数不能有全局变量,否则它们就不是全局的。 Ori's answer 涵盖了堆栈帧中的内容;每次通话都会有一个
        • @Michael Mrozek - 除了可能被编译器优化、内联或以其他方式修改的调用...编译器不需要实现任何特定的调用约定或 ABI。
        • @Michael - 好吧,我错过了编写部分,我想知道如果可执行文件具有不同类型的变量并且在执行期间对单个函数进行递归调用,堆栈的内容是什么.那么对于静态和全局变量,我将它们包括在内以知道它们将驻留在哪里。内存转储和核心转储有什么区别?在这种情况下,我可能使用了不正确的术语并请原谅我。据我所知,核心转储会在应用程序崩溃时提供调用堆栈。但是程序调试期间的内存转储是什么。
        • @Praveen:“内存转储”和“核心转储”之间没有区别。它们是同义词,因为“核心”是一个古老的记忆术语(当计算机内存真的是由编织在网格上的微小铁氧体磁芯制成时)。内存/核心转储包含整个进程可访问内存的映像(尽管通常不包括共享内存区域和大型映射文件)。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-01-03
        • 2012-02-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-04-08
        相关资源
        最近更新 更多