C++ 中的堆栈损坏

Posted

技术标签:

【中文标题】C++ 中的堆栈损坏【英文标题】:Stack corruption in C++ 【发布时间】:2010-10-17 15:19:33 【问题描述】:

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

【问题讨论】:

这些人是纯粹主义者......重申你的问题......除了缓冲区溢出之外,堆栈损坏的常见方法是什么? 【参考方案1】:
    您可以有一个随机/未定义的指针,该指针最终指向堆栈,然后写入。 汇编函数可能会错误地设置/修改/恢复堆栈 宇宙波可以翻转堆栈中的位。 芯片外壳中的放射性元素可能会翻转位。 内核中的任何内容都可能出错并意外更改堆栈内存。

但这些并不是 C++ 特有的,它不知道堆栈。

【讨论】:

好点提 3。为了避免这种情况,我刚刚移动了我的电脑,使它位于我的桌子下面,因此在阴影中。我还需要注意哪些其他预防措施? ;) 其实,最常见的影响芯片的电离辐射源就是芯片封装本身——无处可逃! 用砂纸去除包装。快!【参考方案2】:

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

header.h

struct MyStruct

   int val;
#ifdef LARGEMYSTRUCT
   char padding[16];
#endif

file1.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

#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

【讨论】:

【参考方案3】:

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

void foo()

  my_struct s;
  bar(&s);

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

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

【讨论】:

【参考方案4】:

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

【讨论】:

完全可以回答,只需要不是学者。【参考方案5】:

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

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

【讨论】:

能否举个例子【参考方案6】:

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

【讨论】:

如果我没记错的话,这是 UB - 所以任何事情都有可能发生。 @Equilibrius 绝对是,我只是有第一手经验,它弄乱了堆栈展开。

以上是关于C++ 中的堆栈损坏的主要内容,如果未能解决你的问题,请参考以下文章

指针函数参数损坏,堆栈损坏?

如何解决 ARM Coprtex 上的嵌入式系统编程中的堆栈损坏错误

C/C++程序中的损坏堆栈问题

运行时检查失败 #2 - 变量“e_color”周围的堆栈已损坏

数组变量周围的堆栈损坏

DIY堆栈保护