繁体   English   中英

Memory 覆盖显示在一致位置的 C++ 代码

[英]Memory overwrites in C++ code showing up in consistent locations

我对 memory 覆盖有一个非常不科学的观察,并且很好奇是否有其他人注意到类似的东西,知道为什么,和/或可以告诉我为什么我没有真正看到我认为我看到的东西。

我注意到的是,对于某些 C++ 程序,当我在该程序中有一个 memory 覆盖错误时,它通常(如果不是总是)出现在特定的代码部分中,这通常与带有错误的代码部分无关。 这不是一概而论的观察。 并非所有 C++ 程序都以这种方式运行。 但是当我有一个时,它非常一致。 (没有评论为什么我的代码有足够的 memory 覆盖,我有机会注意到一致的任何东西:))

我不是在问为什么 function1 中的 memory 覆盖可以出现在 function2 中; 这是可以理解的。 我的观察是,在给定程序的整个生命周期中,我们发现 function1、function2、function3、function4 和 function5 中有 memory 次覆盖。 但在每种情况下,我们都发现了问题,因为代码会在 function6 中崩溃。 始终在 function6 中且仅在 function6 中。 这些功能都不相关,也不会触及 function6 使用的任何内容。

在我的一生中,我遇到过两个 C 程序和一个 C++ 程序有这种行为。 这些在不相关的系统和硬件中相隔多年。 我只是觉得这很奇怪,想知道是否有其他人看到过这个。 另外,我怀疑我可能会在我现在正在处理的 C++/JNI/Java 程序中看到相同的模式,但它还很年轻,我还没有足够的命中率来确定模式。

也许这里真正的问题是关于什么将“无声的”memory 损坏升级为实际/正式的崩溃(而不是“只是”更微妙的问题,例如用户可能会或可能不会注意到或识别的意外数据值)。 我不认为这个问题可以普遍回答,因为它在很大程度上取决于编译器的细节、代码、内存数据结构的 memory 布局等。

可以说,在大多数现代(非嵌入式)系统中,有一个 MMU 负责将虚拟(即每个进程)memory 地址转换为物理 memory 地址,并且许多用户空间崩溃是 MMU 生成不可恢复的页面错误,当用户程序试图取消引用一个没有定义的物理等效地址的虚拟地址时。 因此,在这种情况下, function6()可能试图取消引用一个指针,该指针的值已损坏,MMU 无法将其转换为物理地址。 请注意,编译器通常将自己的指针放在堆栈上(以记住当 function 返回时程序的控制流应该返回到哪里),因此即使在没有显式取消引用任何指针的代码中也可能发生错误的指针取消引用。

另一个导致崩溃的常见原因是故意引起的崩溃,由代码调用,该代码注意到它正在使用的数据“在 state 中,这不应该发生”并调用abort()或类似的。 这可能发生在调用了assert()的用户代码中,或者发生在系统提供的代码中,例如管理进程堆的代码。 因此可能是function6()尝试分配或释放堆 memory,这样做使堆管理器有机会检测其数据结构之一中的“不可能状态”并崩溃。 请记住,进程的堆实际上只是一个大数据结构,由使用堆的程序的所有部分共享,因此由程序的一部分引起的堆损坏可能会导致以后崩溃也就不足为奇了由程序的另一个(大部分不相关的)部分也使用堆。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM