C++ 中的堆栈损坏

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/718503/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 16:56:00  来源:igfitidea点击:

Stack corruption in C++

c++stackcorruption

提问by Naveen

In C++, in which way the stack may get corrupted. One way I guess is to overwriting the stack variables by accessing an array beyond its boundaries. Is there any other way that it can get corrupted?

在 C++ 中,堆栈可能以何种方式损坏。我猜的一种方法是通过访问超出其边界的数组来覆盖堆栈变量。有没有其他方法可以损坏它?

回答by Richard Wolf

Violations of the One Definition Rule can lead to stack corruption. The following example looks stupid, but I've seen it a couple of times with different libraries compiled in different configurations.

违反单一定义规则会导致堆栈损坏。下面的例子看起来很愚蠢,但我已经看到过几次使用不同配置编译的不同库。

header.h

头文件.h

struct MyStruct
{
   int val;
#ifdef LARGEMYSTRUCT
   char padding[16];
#endif
}

file1.cpp

文件1.cpp

#define LARGEMYSTRUCT
#include "header.h"

//Here it looks like MyStruct is 20 bytes in size    

void func(MyStruct s)
{
   memset(s.padding, 0, 16); //corrupts the stack as below file2.cpp does not have LARGEMYSTRUCT declared and declares Mystruct with 4 bytes
   return; //Will probably crash here as the return pointer has been overwritten
}

file2.cpp

文件2.cpp

#include "header.h"
//Here it looks like MyStruct is only 4 bytes in size.
extern void func(MyStruct s);

void caller()
{
   MyStruct s;
   func(s); //push four bytes on to the stack
}

回答by Douglas Leeder

  1. You could have a random/undefined pointer that ends up pointing to the stack, and write though that.
  2. An assembly function could incorrectly setup/modify/restore the stack
  3. Cosmic waves could flips bits in the stack.
  4. Radioactive elements in the chip's casing could flip bits.
  5. Anything in the kernel could go wrong and accidentally change your stack memory.
  1. 您可以有一个最终指向堆栈的随机/未定义指针,然后写入。
  2. 汇编函数可能会错误地设置/修改/恢复堆栈
  3. 宇宙波可以翻转堆栈中的位。
  4. 芯片外壳中的放射性元素可以翻转位。
  5. 内核中的任何内容都可能出错并意外更改您的堆栈内存。

But those are not particular to C++, which doesn't have any idea of the stack.

但这些并不是 C++ 所特有的,它对堆栈没有任何概念。

回答by Jimmy J

Taking pointers to stack variables is a good way:

获取堆栈变量的指针是一个好方法:

void foo()
{
  my_struct s;
  bar(&s);
}

If bar keeps a copy of the pointer then anything can happen in the future.

如果 bar 保留指针的副本,那么将来任何事情都可能发生。

Summing up: Stack corruption happens when there's stray pointers pointing to the stack.

总结:当存在指向堆栈的杂散指针时,就会发生堆栈损坏。

回答by dirkgently

The C++ standard does not define stack/heap. Further, there are a number of ways to invoke undefined behavior in a program -- all of which may corrupt your stack (it's UB, after all). The short answer is -- your question is too vague to have a meaningful answer.

C++ 标准没有定义堆栈/堆。此外,有多种方法可以在程序中调用未定义的行为——所有这些方法都可能破坏您的堆栈(毕竟它是 UB)。简短的回答是——您的问题太模糊,无法给出有意义的答案。

回答by peterchen

Calling a function with the wrong calling convention.

使用错误的调用约定调用函数。

(though this is technically compiler-specific, not a question of C++, every C++ compiler has to deal with that.)

(虽然这在技术上是特定于编译器的,而不是 C++ 的问题,但每个 C++ 编译器都必须处理它。)

回答by daramarak

Throwing an exception inside a destructor is a good candidate. It would mess up the stack unwinding.

在析构函数中抛出异常是一个不错的选择。它会弄乱堆栈展开。