Buried in the long list of Windows bug check codes is this guy:
Bug Check 0x13: EMPTY_THREAD_REAPER_LIST
The EMPTY_THREAD_REAPER_LIST bug check has a value of 0x00000013.
This bug check appears very infrequently.
That’s all it says.
What is the origin story of this bug check code?
Friend of the blog Malcolm Smith explained to me that this bug check code was introduced early in the development of Windows NT, and it may even have been used in some beta builds, but no released version of Windows NT ever used it. Nevertheless, the number was assigned, and you don’t want to reuse an assigned number, because that creates confusion if somebody running a beta build encounters bug check 0x00000013
and the bug gets sent to whatever component got the reassigned bug check code. These numbers don’t take up any space, and there are four billion of them, so losing one to history is no big deal.
Okay, so this bug check code is no longer used. But just out of curiosity, what is a thread reaper anyway?
In the Windows kernel, objects are generally responsible for destroying themselves. This doesn’t pose a problem for most categories of objects. But threads are a little stuck: Threads can destroy themselves for the most part, but the thing they can’t destroy is their own stack, because they’re executing on that stack.
Therefore, when a thread terminates and cleans itself up, it cleans up everything it can, and then just before dying, it notifies the thread reaper to harvest its carcass: The thread reaper is a component whose sole purpose is to free the stacks of expired threads.
My guess is that EMPTY_
originally meant that the thread reaper was told to reap a thread, but there was no thread to reap.
The thread reaper must have been redesigned in a way that this error can no longer occur (or at least if the list is empty, it’s not an error any more), and this bug check code is never generated. The code number has a name, but no purpose aside from hanging around in the documentation and tickling the curiosity of people who stumble across it.
Bonus chatter: Andrew Richards took the time to query the Windows Error Reporting database to see whether any systems had encountered this mythical EMPTY_
bug check code in the past 30 days.¹ And to his surprise, he found one!
But upon closer inspection, it was a false alarm. The bug check was really 0x113
, also known as VIDEO_
, but there was a memory failure on the system, and a bit flip changed 0x00000113
into 0x00000013
.
Bonus chatter: There are many web sites and videos purporting to help you fix EMPTY_
crashes. They make up reasons for why this error could occur (“not enough free disk space”, “incompatible device drivers”, “you installed EMPTY_
¹ Windows Error Reporting crash dumps are retained for only 30 days, in order to comply with various governmental regulations.
Needs more cowbell!
Great…. now I have Blue Oyster Cult stuck in my head.
Gotta love seeing a bit flip ending up in a blog post about something else.
Some part of the story is missing here. In old versions of NT, a thread does free its own stack: just before dying, it sets %esp to some temporary buffer in the TEB, and then calls NtFreeVirtualMemory() on the stack. Maybe the reaper kicked in only when a thread died abnormally?
By that logic: Who frees the TEB then, if there is currently a thread executing from it? I guess the answer is: the thread reaper. Everything Raymond said still applies, except the thread reaper is freeing the TEB instead of the stack now.
The statistical likelihood is that other kernels will arise. There will one day be empty thread reaper list bugchecks
I’m still waiting for those lemon-soaked paper napkins.
I like that you posted this story on Halloween. Very appropriate.
The
13
is a nice touch too.