What is the thread reaper?

Raymond Chen

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_THREAD_REAPER_LIST 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_THREAD_REAPER_LIST 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_DXGKRNL_FATAL_ERROR, 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_THREAD_REAPER_LIST crashes. They make up reasons for why this error could occur (“not enough free disk space”, “incompatible device drivers”, “you installed EMPTY_THREAD_REAPER_LIST-related software”) and make up troubleshooting steps (“restart in safe mode”, “update drivers”, and the ever-present “run sfc /scannow”). Welcome to the world of auto-generated content farming.

¹ Windows Error Reporting crash dumps are retained for only 30 days, in order to comply with various governmental regulations.

9 comments

Discussion is closed. Login to edit/delete existing comments.

  • Sunil Joshi 1

    I like that you posted this story on Halloween. Very appropriate.

    • Justine Krejcha 0

      The 13 is a nice touch too.

  • Matthew van Eerde (^_^)Microsoft employee 2

    The statistical likelihood is that other kernels will arise. There will one day be empty thread reaper list bugchecks

    • Michael Dunn 1

      I’m still waiting for those lemon-soaked paper napkins.

  • Leif Strand 0

    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?

    • Marek Knápek 0

      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.

  • Lance McCarthy 0

    Gotta love seeing a bit flip ending up in a blog post about something else.

  • Brian Boorman 0

    Great…. now I have Blue Oyster Cult stuck in my head.

  • David Streeter 1

    Needs more cowbell!

Feedback usabilla icon