ERROR_ARENA_TRASHED 错误代码的历史是什么?

The Old New Thing (Raymond Chen) 新闻

摘要

探讨 ERROR_ARENA_TRASHED 错误代码在 MS-DOS 中的起源、其在内存管理中的含义,以及为何该代码不再用于 Win32 却作为遗留代码继续存在。

<p>错误代码 7 是 <code>ERROR_<wbr />ARENA_<wbr />TRASHED</code>。这是什么意思?听起来像是一支重金属乐队失控,把他们租用的表演区搞得一团糟。</p> <p>此错误消息继承自 MS-DOS。MS-DOS 内部通过一系列大小可变的内存块来管理内存,每个内存块前面都有一个 16 字节的块,称为 <a href="https://github.com/microsoft/MS-DOS/blob/2d04cacc5322951f187bb17e017c12920ac8ebe2/v2.0/source/DOSSYM.ASM#L636">arena(区域)</a>:</p> <pre>arena STRUC arena_signature DB ? ; 4D for valid item, 5A for last item arena_owner DW ? ; owner of arena item arena_size DW ? ; size in paragraphs of item arena ENDS </pre> <p><code>arena_owner</code> 是分配该内存的进程的 PDB,如果内存空闲则为零。每个 arena 签名为 <tt>0x4D</tt>(ASCII 大写字母 M),除了最后一个签名为 <tt>0x5A</tt>(ASCII 大写字母 Z)。没错,这些是 Mark Zbikowski 的名字首字母。</p> <p>当遍历内存块时,例如为了满足分配请求而搜索内存时,如果 MS-DOS 发现签名既不是 <tt>0x4D</tt> 也不是 <tt>0x5A</tt>,则会声明这些 arena 已被&#8220;破坏&#8221;(损坏)¹ 并 <a href="https://github.com/microsoft/MS-DOS/blob/2d04cacc5322951f187bb17e017c12920ac8ebe2/v2.0/source/ALLOC.ASM#L177">返回 <code>ERROR_<wbr />ARENA_<wbr />TRASHED</code></a>。</p> <p>这是一个 MS-DOS 特有的错误代码。Win32 并不使用它。²</p> <p>由于它是一个残留的错误代码(类似于 <a title="What is the thread reaper?" href="https://devblogs.microsoft.com/oldnewthing/20231031-00/?p=108944"> <code>EMPTY_<wbr />THREAD_<wbr />REAPER_<wbr />LIST</code></a>),因此在模拟错误条件时很方便使用,因为你可以相当确信,如果看到错误 7,它来自你的测试工具,而不是真正的系统错误。</p> <p>该错误消息未被使用这一事实,让许多声称能帮你&#8220;修复&#8221;问题的网站令人怀疑。如果你阅读他们对&#8220;这个错误是什么意思&#8221;的解释,那不过是一堆模糊的文字,诸如:你知道,有时候计算机运行不太正常,会遇到错误,或者可能是硬件冲突,或者是系统文件损坏。但不知何故,尽管他们完全不知道这个错误意味着什么,却仍然对解决问题的步骤充满信心。(通常是执行系统扫描、系统文件检查和检查驱动程序更新。)</p> <p>¹ 使用俚语&#8220;trashed&#8221;进一步证明了 Microsoft 开发者 <a title="The Microsoft/IBM joint development was built on mutual respect, wait, is respect the right word?" href="https://devblogs.microsoft.com/oldnewthing/20240827-00/?p=110186">只是一群缺乏纪律的黑客</a>。</p> <p>² 嗯,至少 Win32 内核不使用它。我确实看到有一些用户态组件使用它来表示内部数据结构已损坏,至少这与该错误的原始含义精神一致。</p> <p>此文 <a href="https://devblogs.microsoft.com/oldnewthing/20260519-00/?p=112339">&lt;CODE&gt;ERROR_&lt;WBR&gt;ARENA_&lt;WBR&gt;TRASHED&lt;/CODE&gt; 错误代码的历史是什么?</a> 首次出现在 <a href="https://devblogs.microsoft.com/oldnewthing">The Old New Thing</a> 上。</p>
查看原文
查看缓存全文

缓存时间: 2026/05/20 03:35

# `ERROR_ARENA_TRASHED` 错误代码的由来是什么? – 《陈年老事》 来源:https://devblogs.microsoft.com/oldnewthing/20260519-00?p=112339 错误代码 7 是 `ERROR_ARENA_TRASHED`。这到底是什么意思?听起来就像一支重金属乐队在他们租来的演出场地上胡闹,搞得一团糟。 这个错误消息是从 MS-DOS 继承来的。MS-DOS 内部以一系列可变大小的内存块来管理内存,每个内存块前都有一个 16 字节的块,称为 arena(https://github.com/microsoft/MS-DOS/blob/2d04cacc5322951f187bb17e017c12920ac8ebe2/v2.0/source/DOSSYM.ASM#L636): ```asm arena STRUC arena_signature DB ? ; 4D 表示有效项,5A 表示最后一项 arena_owner DW ? ; arena 项的所属者 arena_size DW ? ; 项的大小(以节为单位) arena ENDS ``` `arena_owner` 是分配该内存的进程的 PDB,如果内存空闲则为零。每个 arena 签名为 `0x4D`(ASCII 大写字母 M),除了最后一个签名为 `0x5A`(ASCII 大写字母 Z)外。没错,这些正是 Mark Zbikowski 姓名的首字母。 当遍历内存块时(例如在搜索可用内存以满足分配请求时),如果 MS-DOS 发现签名既不是 `0x4D` 也不是 `0x5A`,它就会声明这些 arena 已经“被损坏”(trashed)¹,并返回 `ERROR_ARENA_TRASHED`(https://github.com/microsoft/MS-DOS/blob/2d04cacc5322951f187bb17e017c12920ac8ebe2/v2.0/source/ALLOC.ASM#L177)。 这是一个 MS-DOS 特有的错误代码。Win32 并不使用它²。 由于它是一个残余的错误代码(类似于 `EMPTY_THREAD_REAPER_LIST`(https://devblogs.microsoft.com/oldnewthing/20231031-00/?p=108944)),因此很适合在模拟错误条件时使用,因为你可以相当确信,如果你看到错误代码 7,它来自你的测试框架,而不是真正的系统错误。 这个错误消息不再被使用的事实,让许多声称能帮你“修复”该问题的网站显得形迹可疑。如果你阅读他们关于“这个错误是什么意思”的解释,那只是一堆含糊其辞的文字,说什么“你知道的,有时候计算机运行得不太顺利,会遇到错误”,或者可能是硬件冲突,又或者是系统文件损坏。但不知何故,尽管他们完全不知道这个错误是什么意思,他们仍然对你应该采取的修复步骤信心十足。(通常是执行系统扫描、系统文件检查以及检查驱动程序更新。) ¹ 使用俚语“trashed”进一步证明微软开发者不过是一群缺乏纪律的黑客(https://devblogs.microsoft.com/oldnewthing/20240827-00/?p=110186)。 ² 嗯,至少 Win32 内核不使用它。但我确实看到一些用户模式组件用它来表示内部数据结构已损坏,至少这与该错误的原始含义在精神上是一致的。 ### 分类 ### 主题 ## 作者 Raymond Chen Raymond 参与 Windows 的演进已有 30 多年。2003 年,他创办了一个名为《陈年老事》的网站,该网站的人气远超他最疯狂的想象——这个发展至今仍让他感到不寒而栗。该网站后来催生了一本书,巧合的是书的名字也叫《陈年老事》(Addison Wesley 出版社,2007 年)。他偶尔会出现在 Windows 开发文档的推特账号上,讲述一些毫无信息量的故事。

相似文章

关于滥用Windows窗口类额外字节的兼容性说明

The Old New Thing (Raymond Chen)

Raymond Chen 讨论了一个历史性的 Windows 兼容性问题,其中一些 16 位程序滥用窗口类额外字节来存储私有数据,以及微软如何在保持向后兼容性的同时,对 32 位和 64 位程序堵住了这个漏洞。

核心转储流行病学:修复一个18年的旧bug

OpenAI Blog

OpenAI工程师详细描述了Rockset的C++数据基础设施中看似不可能的崩溃的诊断过程,揭示了一个Azure上的静默硬件损坏bug以及GNU libunwind中存在18年的竞态条件,最终通过崩溃数据的流行病学分析得以解决。

为什么Windows娱乐包没有通过模拟器直接运行MS-DOS版本? 主要原因在于当时的软硬件环境与技术限制: 1. **性能与兼容性问题**:早期的Windows系统(如Windows 3.x)本身就是MS-DOS的图形界面扩展,其自身仍高度依赖DOS底层环境。若通过模拟器运行DOS版本游戏,会引入额外的性能开销,可能导致游戏在原本就有限的硬件上无法流畅运行。 2. **设计哲学差异**:Windows娱乐包的目标是为Windows平台提供**原生体验**。这些游戏(如《扫雷》《纸牌》)被重新设计为适配Windows图形界面、鼠标操作和多任务环境,而非简单移植DOS版本。这种原生化有助于推广Windows界面交互方式。 3. **技术架构限制**:当时的Windows并未内置完整的模拟器功能。虽然存在如`NTVDM`(在Windows NT内)等DOS兼容层,但Windows 3.x时代仍基于DOS内核,资源管理方式不同,直接集成模拟器并不现实。 4. **商业策略考量**:微软希望用户从DOS过渡到Windows,通过为Windows平台提供**独有内容**来增强系统吸引力。若仅模拟DOS游戏,可能反而削弱用户升级Windows的动力。 简言之,这是一次面向新时代操作系统的**主动设计选择**,而非技术上的偷懒。

The Old New Thing (Raymond Chen)

本文阐述了Windows娱乐包未采用模拟技术运行MS-DOS游戏的原因:受1990年代硬件限制,内存容量不足且缺乏虚拟化支持,导致该方案不切实际,用户体验极差。