gpt4 book ai didi

c++ - 为什么在函数栈上返回值不安全

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:40:04 25 4
gpt4 key购买 nike

我在阅读 bruce eckel 时遇到了以下段落..他试图解释为什么函数在堆栈上返回值是不安全的

Now imagine what would happen if an ordinary function tried to return values on the stack
.you can,t touch any part of the stack that's above the return address,so the function would have to push the values below the return address.But when the assembly language return is executed ,the stack pointer must be pointing to the return address(or right below it depending on your machine),so right before the RETURN ,function must move the stack pointer up,thus clearing of all the local variables.If you are trying to return values on the stack below the return address,you become vulnerable at the moment because an interrupt could come along.The ISR would come the stack pointer down to hold its return address and its local variables and overwrite your return value

你愿意帮助我理解粗斜体文本吗?

最佳答案

假设您的应用程序中某处有以下调用堆栈:

  1. 主程序
  2. Function1 的局部变量
  3. Function2 的局部变量 <-- 堆栈指针

在这种情况下,main 调用 function1,function1 调用 function2。

现在假设function2调用function3,function3的返回值入栈:

  1. 主程序
  2. Function1 的局部变量
  3. Function2 的局部变量
  4. Function3 的局部变量,包括返回值 <-- STACK POINTER

Function3 把返回值存入栈中,然后返回。返回的意思是,再次减少堆栈指针,所以堆栈变成这样:

  1. 主程序
  2. Function1 的局部变量
  3. Function2 的局部变量 <-- 堆栈指针

你看,function3 的栈帧不在这里了。

好吧,实际上我撒了一点谎。堆栈框架仍然存在:

  1. 主程序
  2. Function1 的局部变量
  3. Function2 的局部变量 <-- 堆栈指针
  4. Function3的局部变量,包括返回值

因此仍然访问堆栈以获取返回值似乎是安全的。

但是,如果在 function3 返回之后有一个中断,但是在 function2 从堆栈中获取返回值之前,我们会得到这个:

  1. 主程序
  2. Function1 的局部变量
  3. Function2 的局部变量
  4. 中断函数的局部变量<-- STACK POINTER

而现在栈帧真的被覆盖了,我们急需的返回值也没有了。

这就是为什么在堆栈上返回返回值是不安全的。

问题类似于这段简单的 C 代码中显示的问题:

char *buf = (char *)malloc(100*sizeof(char *));
strcpy (buf, "Hello World");
free (buf);
printf ("Buffer is %s\n",buf);

大多数情况下,用于 buf 的内存仍将包含“Hello World”内容,但如果有人能够在调用 free 之后但在调用 printf 之前分配内存,则可能会出现可怕的错误。一个这样的例子是在多线程应用程序中(我们已经在内部遇到过这个问题),如下所示:

THREAD 1:                                  THREAD 2:
--------- ---------
char *buf = (char *)malloc(100);
strcpy (buf, "Hello World");
free (buf);
char *mybuf = (char *)malloc(100);
strcpy (mybuf, "This is my string");
printf ("Buffer is %s\n",buf);

线程 1 的 printf 现在可以打印“Hello World”,或者它可以打印“This is my string”。任何事情都有可能发生。

关于c++ - 为什么在函数栈上返回值不安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5185773/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com