为什么它不安全返回值在函数堆栈 [英] why its not safe to return value on function stack

查看:129
本文介绍了为什么它不安全返回值在函数堆栈的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I came across the following paragraph while reading bruce eckel..where he was trying to explain why its not safe for function to return value on stack


现在想象如果一个普通函数试图在堆栈上返回值

会发生什么,你可以触摸返回地址上面的堆栈的任何部分,所以函数必须 但是当执行汇编语言返回时,堆栈指针必须指向返回地址(或者正好在它的下面,取决于你的机器),因此在RETURN之前,函数必须将堆栈指针向上移动,从而清除所有局部变量。如果您尝试在堆栈上的返回地址下方返回值, 因为中断可能会发生。ISR将向下移动堆栈指针以保持其返回地址及其局部变量并覆盖您的返回值

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

推荐答案

假设您想要帮助我理解粗体斜体文本吗?您的应用程序中有一个以下的调用堆栈:

Suppose that you have the following call stack somewhere in your application:


  1. 主例程

  2. Function1的局部变量

  3. Function2的局部变量< - STACK POINTER

和function1调用function2。

In this case main calls function1, and function1 calls function2.

现在假设function2调用function3,并且函数3的返回值在堆栈上返回:

Now suppose that function2 calls function3, and the return value of function3 is returned on the stack:


  1. 主例程

  2. Function1的局部变量

  3. Function2的局部变量

  4. Function3的局部变量,包括返回值< - STACK POINTER

  1. Main routine
  2. Function1's local variables
  3. Function2's local variables
  4. Function3's local variables, including the return value <-- STACK POINTER



函数3将返回值存储在堆栈中,然后返回。返回意味着再次减少堆栈指针,因此堆栈变成:

Function3 stores the return value on the stack, and then returns. Returning means, decreasing the stack pointer again, so the stack becomes this:


  1. 主例程

  2. Function1的局部变量

  3. Function2的局部变量< - STACK POINTER

堆栈框架不在这里了。

好吧,我说了一下。


  1. 主程序

  2. Function1的局部变量

  3. Function2的局部变量< - STACK POINTER

  4. Function3的局部变量,包括返回值

  1. Main routine
  2. Function1's local variables
  3. Function2's local variables <-- STACK POINTER
  4. Function3's local variables, including the return value

所以看来仍然可以访问堆栈以获取返回值。

So it seems safe to still access the stack to get the return value.

但是,如果函数3返回后有一个中断, BEFORE function2从栈中获取返回值,我们得到:

But, if there is an interrupt AFTER function3 has returned, but BEFORE function2 get's the return value from the stack, we get this:


  1. 主例程

  2. Function1局部变量

  3. Function2的局部变量

  4. 中断函数的局部变量< - STACK POINTER

  1. Main routine
  2. Function1's local variables
  3. Function2's local variables
  4. Interrupt function's local variables <-- STACK POINTER

现在堆栈框架真的被覆盖,我们迫切需要的返回值已经消失了。

And now the stack frame is really overwritten, and the return value that we desperately needed has gone.

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

That's why returning a return value on the stack is not safe.

问题类似于这个简单的C代码:

The problem is similar to the one shown in this simple piece of C code:

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

大多数时候,用于buf的内存将仍然具有内容Hello World ,但它可以去可怕的错误,如果有人能够分配内存后,free被调用,但在printf被调用之前。一个这样的例子是在多线程应用程序(我们已经在内部遇到这个问题),如下所示:

Most of the times, the memory that was used for buf will still have the contents "Hello World", but it can go horribily wrong if someone is able to allocate memory after free has been called, but before printf is called. One such example is in multi-threaded applications (and we already encountered this problem internally), like shown here:

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);

printf是Thread 1现在可以打印Hello World,或者可以打印This is my串。任何事情都可能发生。

The printf is Thread 1 may now print "Hello World", or it may print "This is my string". Anything can happen.

这篇关于为什么它不安全返回值在函数堆栈的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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