栈里面有什么? [英] What's inside the stack?

查看:28
本文介绍了栈里面有什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我运行一个程序,就像

If I run a program, just like

#include <stdio.h>
int main(int argc, char *argv[], char *env[]) {
  printf("My references are at %p, %p, %p
", &argc, &argv, &env);
}

我们可以看到这些区域实际上在堆栈中.但还有什么?如果我们循环遍历 Linux 3.5.3 中的所有值(例如,直到 segfault),我们可以看到一些奇怪的数字,以及由一堆零分隔的两个区域,可能是为了防止覆盖环境变量不小心.

We can see that those regions are actually in the stack. But what else is there? If we ran a loop through all the values in Linux 3.5.3 (for example, until segfault) we can see some weird numbers, and kind of two regions, separated by a bunch of zeros, maybe to try to prevent overwriting the environment variables accidentally.

无论如何,在第一个区域中肯定有很多数字,例如每个函数调用的所有帧.

Anyway, in the first region there must be a lot of numbers, such as all the frames for each function call.

我们如何区分每一帧的结束,参数在哪里,如果编译器添加了金丝雀,返回地址,CPU状态等等?

How could we distinguish the end of each frame, where the parameters are, where the canary if the compiler added one, return address, CPU status and such?

推荐答案

栈的内容基本是:

  • 无论操作系统传递给程序什么.
  • 调用框架(也称为堆栈框架、激活区域……)

操作系统将什么传递给程序?典型的 *nix 会将环境、参数传递给程序,可能还有一些辅助信息,以及指向它们的指针以传递给 main().

What does the OS pass to the program? A typical *nix will pass the environment, arguments to the program, possibly some auxiliary information, and pointers to them to be passed to main().

在 Linux 中,您会看到:

In Linux, you'll see:

  • 一个空值
  • 程序的文件名.
  • 环境字符串
  • 参数字符串(包括argv[0])
  • 用零填充
  • auxv数组,用于将信息从内核传递给程序
  • 指向环境字符串的指针,以 NULL 指针结尾
  • 指向参数字符串的指针,以 NULL 指针结尾
  • argc
  • a NULL
  • the filename for the program.
  • environment strings
  • argument strings (including argv[0])
  • padding full of zeros
  • the auxv array, used to pass information from the kernel to the program
  • pointers to environment strings, ended by a NULL pointer
  • pointers to argument strings, ended by a NULL pointer
  • argc

然后,下面是堆栈帧,其中包含:

Then, below that are stack frames, which contain:

  • 参数
  • 退货地址
  • 可能是帧指针的旧值
  • 可能是金丝雀
  • 局部变量
  • 一些填充,用于对齐目的

你怎么知道每个堆栈帧中哪个是哪个?编译器知道,所以它只是适当地处理它在堆栈帧中的位置.如果可用,调试器可以以调试信息的形式为每个函数使用注释.否则,如果存在帧指针,您可以识别与它相关的事物:局部变量位于帧指针下方,参数位于堆栈指针上方.否则,您必须使用启发式算法,看起来像代码地址的东西可能是代码地址,但有时这会导致不正确且烦人的堆栈跟踪.

How do you know which is which in each stack frame? The compiler knows, so it just treats its location in the stack frame appropriately. Debuggers can use annotations for each function in the form of debug info, if available. Otherwise, if there is a frame pointer, you can identify things relative to it: local variables are below the frame pointer, arguments are above the stack pointer. Otherwise, you must use heuristics, things that look like code addresses are probably code addresses, but sometimes this results in incorrect and annoying stack traces.

这篇关于栈里面有什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆