什么是堆栈里面呢? [英] What's inside the stack?

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

问题描述

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

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\n", &argc, &argv, &env);
}

我们可以看到,这些区域实际上是在栈。
但是,还有什么呢?如果我们的Linux 3.5.3跑过所有值循环(例如,直到段错误),我们可以看到一些奇怪的号码,那种两个区域,由一串零分开的,也许要尽量prevent覆盖环境变量意外。

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?

推荐答案

堆栈的内容基本上是:


  • 无论操作系统传递给该程序。

  • 呼叫帧(也称为栈帧,激活区域,...)

什么是OS传递给程序?一个典型的* 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:


  • 一个NULL

  • 文件名的程序。

  • 环境字符串

  • 参数字符串(包括的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:


  • 参数

  • 返回地址

  • 可能帧指针的旧值

  • 可能是金丝雀

  • 局部变量

  • 某些填充,对齐的目的

你怎么知道哪个是哪个在每个堆栈帧?编译器知道,所以它只是在栈帧对待自己的位置适当。调试器能够在调试信息的形式,如果可以使用注释为每个函数。否则,如果有一个帧指针,可以识别的东西相对于它:局部变量帧指针下面,参数是堆栈指针的上方。否则,您必须使用启发式,事情看起来像code地址可能是code类地址,但有时这会导致不正确的,恼人的堆栈跟踪。

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天全站免登陆