The test could crash Word 97. The failure was sporadic, yet the script brought it back often enough that a team near release had no reason to gamble on users never seeing it.

Then somebody ran the debugger.

No crash.

Raymond Chen tells the story nearly thirty years later from a colleague’s account. The bug affected a fairly common code path and was considered ship-stopping: serious enough to hold the release until the team understood it. The lab even had a script that triggered the failure with fairly good reliability.1

They had something rare and valuable in bug hunting: a script that could summon the failure. Then the moment a debugger joined the experiment, that advantage evaporated.

Chen does not say exactly why the crash vanished. Chen leaves that hole open. A debugger can disturb timing, memory state, code through breakpoints, and plenty more, but none of those explanations is identified in the account. Picking one would be fan fiction for engineers.

Another observer

At one point the team considered hauling in hardware that most software developers only knew as legend: an ICE, an in-circuit emulator.1

In Chen’s account, this hardware effectively stands in for the target machine’s CPU. A cable plugs into the processor socket while the emulator reproduces the electrical signals a real processor would generate. Engineers can inspect memory and events from outside the system they are trying to understand.1

The appeal was almost physical: if software observation changed the result, move the observation outside the target machine’s normal CPU path.

The ICE never becomes the hero.

Instead, developers notice something much more ordinary about the failing machines: most came from the same manufacturer, and they had been built before a certain date. That cluster led them to a CPU erratum consistent with the manufacturing dates of the affected systems.1

Chen names neither the manufacturer nor the processor model. He also does not publish the exact instruction pattern. The evidence therefore stops at a careful statement: a known hardware erratum could be triggered by a particular code sequence under specific conditions.

The suspicion had moved down a layer. Word could be emitting legal machine code while a particular processor revision still mishandled the exact sequence under the exact wrong conditions.

About 150 patterns

The compiler used by the Word team had already received an update that avoided the offending sequence.1 That presented the obvious fix: rebuild Word and let the newer code generator avoid the pattern everywhere. Near the end of a release, though, “obvious” and “safe” are annoyingly different words. The team kept the old toolchain.

Instead it wrote a tool that scanned the existing binaries for every occurrence of the sequence capable of triggering the erratum. It found around 150 occurrences.1

This is where the primary post is better than the retelling. The Register compresses the search down to one occurrence.5 Chen says the scanner actually found about 150 candidate sequences. The useful filter came next.

The processor bug required one more condition. The sequence also had to span a memory page boundary. Of those roughly 150 occurrences, only one did.1

And the testers had found it in practice.

A page boundary is an excellent ingredient for a miserable bug. The same bytes can sit harmlessly in one place and become dangerous when their address makes the sequence straddle two pages. Reading the source alone will never show that condition. The address is part of the bug.

So the rarity lived less in the instruction pattern than in its address. About 150 candidates existed. Only one landed where every condition lined up.

Do not recompile

The newer compiler still looks like the adult solution. Unfortunately Word 97 was in the part of the schedule where adult solutions can have enormous blast radii.

Microsoft called this stage escrow. Chen’s 2026 explanation is wonderfully final: this is the build expected to ship if it clears quality and reliability targets.2 The culture around it is basically hands off unless the emergency is real.

Changing compilers at that point does not alter one bad sequence. It can regenerate a large amount of machine code.

The risk is not necessarily that the new compiler contains a bug. Chen gives a nastier example: an existing source bug can remain hidden by the old compiler’s layout of local variables. Change compiler, change the layout, and an uninitialized value that happened to look harmless can suddenly become zero.1

A perfectly correct new compiler could therefore expose a perfectly old defect simply by arranging locals differently in memory.

Chen has a nastier example from Windows 3.1. A tiny fix added one global variable. That moved the globals sitting after it, so an old corruption bug that had harmlessly been writing zero onto an already-zero variable suddenly hit something important.4 Nothing about the bad write was new. Its victim was.

Near release, source diff size is a poor measure of actual change size.

A useless byte

The shipped workaround fit into one instruction: nop.

A NOP, short for no operation, deliberately contributes no useful result. The processor consumes it and moves on. Dropping one into the offending pattern was enough to stop that exact dangerous sequence from reaching the CPU unchanged.1

It did not fix the processor. It was not a conceptual repair of Word’s source code either. It was a targeted avoidance of a known hardware condition.

Chen described another case in 2011 where this sort of surgery was routine, this time involving early B1 stepping 80386 processors and Windows 95.3 Several errata on those chips depended on exact adjacency between instruction types. Inserting a NOP between them could break the dangerous combination. In some cases even an ordinary NOP fell into an inconvenient category, so engineers used a specially prefixed form.3

The 2011 story is a useful analogy and a terrible identification tool. It does not tell us that Word 97 hit the same 80386 B1 issue. What it does show is the engineering pattern: a NOP can act like a tiny spacer in an x86 instruction stream, breaking a combination the hardware dislikes.

The Word 97 patch follows that same minimal-mitigation philosophy.

The known bug

There is something counterintuitive about the decision. The team now knew of a newer compiler that generated safer code around the erratum. It still kept the older toolchain and modified the binary directly.

Early in a project, binary-patching around a CPU bug should raise eyebrows. A few steps from shipping, the arithmetic is different. The existing build had accumulated an awkward asset: lots of boring test evidence. Source, compiler, options and generated binaries had been exercised together for weeks or months. Recompile everything and some of that evidence stops applying to the machine code you now intend to ship.

The NOP introduces a much smaller uncertainty. The team can verify that the one page-crossing occurrence no longer triggers the CPU bug and that the test scenario stops crashing, without asking all of Word 97 to become a new build in every meaningful sense.

Chen’s older Windows 3.1 story phrases the release lesson almost backwards from school deadlines: as shipping gets closer, the rate of change should slow, because regression risk starts costing more than many fixes are worth.4 Serious bugs still move the code. They just need a much better reason to move a lot of it.

The ghost remains

The funniest part is still the one the story never closes: why did attaching the debugger make this particular crash vanish?

The published account does not say.1 Maybe the team knew at the time. Maybe the detail was lost. Maybe it simply stopped mattering once the erratum was identified. We do not need to choose for them.

What the story establishes is already enough.

A software crash led to a hardware defect. The dangerous pattern existed around 150 times, but only one copy occupied the wrong address relationship. A newer compiler knew how to avoid the pattern, but switching to it would broaden the risk to the whole product. An instruction that does nothing therefore became the safest fix.

The fix therefore ends with an instruction designed to do no useful work. For once, doing nothing was exactly the feature the release needed.