访问违规可以是一个伪装的内存不足错误吗

Can an access violation be a disguised out-of-memory error?

本文关键字:伪装 一个 内存不足 错误 访问      更新时间:2023-10-16

我正在调试一个64位C++(托管)崩溃转储(访问冲突)。

转储的总大小为32.374.535 kb。

该应用程序是多线程的,相应的调用堆栈只提到mscvrt.dll!memcpy(我不知道是哪个线程在创建这个)。显然没有相应的源代码。

Visual StudioLocals窗口为空。

未处理的异常提到Access violation writing location 0x000000F02A6BB000,但在那个位置上,似乎什么都没有:

0x000000F02A6BAF84  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ..............................................................
0x000000F02A6BAFC2  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ..............................................................
0x000000F02A6BB000  ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??  .............................................................. <= here it is.
0x000000F02A6BB03E  ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??  ..............................................................

我看不出为什么在这个内存位置上写入会引起任何问题,因此我相信(根据转储的大小)我正在处理内存错误(这意味着不可能将某些内容复制到内存中,因为已经使用了太多内存,没有空间了)。然而,如果这是真的,那么在那个内存位置难道不应该有一些信息吗?

有人知道这件事吗?

如果没有看到源代码,就无法知道如果遇到内存不足错误,它可能会做什么。当然,有很多程序不会检查每个内存分配是否存在故障,因此它们的代码可能会完全偏离轨道。

未经检查的内存不足错误最常见的结果是访问违规,但通常发生在一个非常小或有一些明显非标准模式的地址。这是因为许多内存分配函数在内存不足时返回零,而检查失败可能会导致访问接近返回值的地址。此外,有些函数未初始化结果,并返回一个单独的错误。如果不检查该错误,可能会导致使用未初始化的值访问内存,这通常看起来很奇怪。

在这里,地址看起来很合理。但谁知道呢。也许代码会分配一个新的缓冲区,释放旧的缓冲区并将旧地址切换为新地址,但在出现错误时,不会切换地址,而是释放旧地址,从而导致释放后的访问。没有源代码,就无从知晓。

直观地说,它在我看来并不像是内存不足的错误。一些设计不佳的操作系统上的内存分配系统服务在分配内存失败时将成功返回值。尽管Windoze有很多缺陷,但我不相信它是这样一个系统。如果你运行的系统确实会延迟分配,那么我会怀疑你的怀疑。

我认为,内存溢出导致对尚未映射到地址空间的页面进行写入。

正如Scheff和Peter的评论中所提到的,访问违规实际上可能是内存不足错误(或其他类型的内存相关错误)。

在这种特殊情况下,转储的大尺寸(±33Gb)表明应用程序(与其他应用程序一起)可能会消耗太多内存。