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 上的嵌入式系统编程中的堆栈损坏错误