What is SysFader and why is it always crashing?


If you type SysFader into your favorite search engine, you'll find lots of hits from people asking, "What is SysFader, and why is it always crashing Internet Explorer?"

SysFader: iexplore.exe - Application Error
The exception unknown software exception (0xe06d7363) occurred in the application at location 0x7c812afb.

When a program encounters a fatal error, the system crash dialog appears. And it needs to put somebody's name in the title of the dialog to indicate which application crashed. Sure, it has the process name (iexplore.exe), but it has this nagging feeling that it can do better. After all, not everybody will know that "AcroRd32.exe" is "The menu for my favorite restaurant that I was looking at in Adobe Acrobat Reader". So it goes looking for a window that belongs to the thread so it can steal the window's title and use that to help the user understand what it was that crashed.

And if can't find any visible windows, it will go for invisible ones, on the theory that, "Well maybe the application crashed before it could show the window."

Now let's see what happens when we apply this logic to SysFader.

SysFader is a helper window used by Internet Explorer to perform fade-out animations. It really doesn't do much, but it is a window, albeit an invisible one when there are no animations in progress.

SysFader happens to run on a shared worker thread. If that worker thread is being borrowed by some other background task, and that background task crashes, then when the crash dialog appears and looks around for a window to put in the title, it says "Rats, I don't have any visible windows, but I do have this invisible one, so I'll go ahead and put that one in the title bar. Better than nothing."

It's sort of the error-reporting version of the Politician's Fallacy:

  1. A window must be blamed.
  2. This is a window.
  3. Therefore, we must blame it.

It's like your photo appearing in a newspaper article headlined Robbery at Woodgrove Bank, Suspect At Large, not because you're the suspect, but because you happen to have been in the building at the time of the robbery.

Bonus chatter: You probably recognize the exception code as an unhandled C++ exception. Internet Explorer doesn't use C++ exceptions, so the exception most likely came from a plug-in.

[Raymond is currently away; this message was pre-recorded.]

Comments (23)
  1. Goran says:

    "the exception most likely came from a plug-in"… So you want to use C++ in your ATL code? Well, you need to work a bit on what exceptions can be thrown from your code (C++ is BAD when it comes to that), and catch them systematically on any COM boundary. It's not that hard (says the guy who managed to let these babies slip through said COM boundary). (BTW, although you can turn exceptions off, C++ without exceptions is not C++ if you ask me :-)).

  2. So is SysFader a holdover from the old IE 5.5 era "page transitions" feature?

    [Nope. Those happen in-frame (so you can't run them on a background thread). It's the menu fade-out animation. -Raymond]
  3. AC says:

    @Goran: "although you can turn exceptions off, C++ without exceptions is not C++ if you ask me"

    I never really understood what turning off exceptions means.

    What happens when a std::vector<T>.push_back() call fails because it runs out of memory? It should throw std::bad_alloc, but that's disabled?!?

  4. xpclient says:

    Aren't there more invisible windows to blame in Windows 8?

  5. skSdnW says:

    "SysFader is a helper window used by Internet Explorer" does IE even know that this window exists? The IE/OE/Explorer menuband is/was a toolbar+HMENUs and I'm guessing the fade window (fade or slideout added in 2k) is part of the native menu implementation?

    Why not include the name of the module where the exception occurred? It might not work for ATL thunks but in situations where the module is known I'd rather be told about that and not a random window title.

    [The fade-out is IE-provided. This is where IE wants to emulate the system menu fade-out for things that aren't HMENUs. And think about it: What happens if you blame the crashing module? Answer: You end up blaming the messenger. Module A passes an invalid parameter to module B, so module B crashes and gets blamed. "Why does kernel32 crash all the time?" -Raymond]
  6. "What happens when a std::vector<T>.push_back() call fails because it runs out of memory? It should throw std::bad_alloc, but that's disabled?!?"

    My question exactly… I've never bothered to turn exceptions off and see what happens.  Probably something very ugly.  It just seems like breaking the language, and the "wrong" thing to do.

  7. FYI: The new version of ProcDump (v5) (soon to be released) prints the 'msc' exception names when it logs exceptions (1st or 2nd chance).

  8. Cesar says:

    @AC, @JamesJohnston: AFAIK, when you turn off exceptions, the compiler simply does not emit the stack unwinding stuff for your functions. If you call a function which throws, your destructors will not be called, and it might misbehave in other ways. So if you turn off exceptions, you must avoid calling code which can throw.

    Yes, this means you cannot use a lot of the STL. But if you are using C++ just to write directly to the Win32 API and call or implement some COM code (more easily than you would do in C), and are using a non-STL allocator like malloc or HeapAlloc, you can get away with disabling exceptions. Disabling exceptions (and disabling RTTI, another thing you can do in some compilers) allow you to use a subset of C++ as a "better C".

  9. David Walker says:

    There used to be an option in Internet Explorer that I would uncheck (Allow Page Transitions) which I thought was related to allowing pages to visually blend from one page to another… or something.

    I hate menu animations of all kinds, so I turn off everything named "naimate", "fade", and "slide" in Windows Explorer Visual Effects.  Wow, my windows respond faster!  Smooth scrolling is also off, and Wow!  My "page-down" happens faster!

    If I have fewer processes running, that's good too, but I don't expect the fader or the animation code to really be crashing, which echoes what Raymond says here.

  10. Matt says:

    If this is a known problem, why not get the IE people to change the Window name from "SysFader" to "A background thread in Internet Explorer encountered a problem".

    That way this heuristic will stop confusing people when stuff goes wrong.

  11. Paul M. Parks says:

    @Matt: Cute, but then the Spy++ surfers will inundate support with "bug" reports.

  12. alegr1 says:

    Wait? Who thought that creating long-living windows in an arbitrary worker thread is a good idea?

    [Not the IE guys. the SysFader window is destroyed when fading is complete. -Raymond]
  13. Anonymous Coward says:

    Wasn't SysFader a minor villain in the second Star Wars trilogy?

  14. xpclient says:

    Page transitions were unfortunately removed from IE9 just because they were not a "standard".

  15. bdv@inec.ru says:

    IF OS trusts program to provide human-readable information about itself, then instead of hunting for hidden windows more straightforward and simple approach would be just getting program name from EXE VersionInfo

    [If you had more than one copy of the program running (e.g. Acrobat Reader) then you don't know which one crashed. If the crash occurred in a plug-in, then it will be blamed on the host application. And it also leads to questions like "What does the COM Surrogate do and why does it keep crashing?" -Raymond]
  16. ExceptionCurious says:

    It seems that Google Chrome doesn't use C++ exceptions either (google-styleguide.googlecode.com/…/cppguide.xml)

    But I wonder how these complex systems (IE, Chrome) handle error conditions (e.g. what happens when something fail deep inside some function? Do error codes bubble up until the main program loop?)

  17. Neil says:

    @ExceptionCurious Gecko (Firefox) avoids C++ exceptions too. In order to work with STL, it provide its own malloc that simply aborts on OOM. Its other errors are often represented with error codes but sometimes methods just return a boolean success flag.

  18. "If you call a function which throws, your destructors will not be called, and it might misbehave in other ways."

    I would at least hope at least the process gets nuked from orbit at the time the exception is thrown, rather than allowing the program to continue and exhibit undefined behavior…

    What I don't get is why everyone is avoiding exceptions in the first place.  I don't buy the arguments against exceptions in Google Chrome.  Sounds like an excuse not to use RAII.  C# doesn't even have a concept like RAII apart from the limited "using" block, and people have been throw exceptions there for years…

    [In order for the runtime to nuke the process from orbit, the function would need a "catch(…)" which defeats the purpose of disabling exception handling. (I.e., to "disable exception handling" you "enable exception handling"?) Code which interoperates with other languages (or compilers or even versions of compilers) cannot use synchronous C++ exceptions because the C++ synchronous exception ABI is not standardized and can vary from compiler to compiler, compiler version to compiler version. And of course it doesn't work in languages that aren't C++! If you control your program top to bottom and can guarantee that all code was compiled at the same time with the same compiler, then more power to you. But applications which have a plug-in model don't have that luxury. -Raymond]
  19. "In order for the runtime to nuke the process from orbit, the function would need a "catch(…)" "

    No, it would not.  I'm just saying that the compiler should translate the "throw" into throwing a CPU exception, rather than a no-operation.  Divide by zero.  Cause an access violation.  Anything.  Since there's no exception handler, the process should then die right at the "throw".  That way I know right away there's a problem.  I really don't care, I just wouldn't want to ignore the throw and keep pretending like nothing happened!

    I also know the C++ ABI is not standardized.  But this lack of ABI extends beyond exception handling.  If you have to call another library made with a different compiler and/or compiler version, then do it through a C interface (which, by definition, has no C++ exceptions).  For every web browser I know, plug-ins go through a C interface (including COM).  Whether plug-ins use C++ or the browser uses C++ is inconsequential, as long as they stick to a C interface (which includes not allowing exceptions to pass through the interface).

    Your argument can really be generalized into "don't use C++, because it doesn't have an ABI" – like this:  "Code which interoperates with other languages … cannot use any C++ features because the C++ ABI is not standardized and can vary from compiler to compiler….."  Picking on one specific C++ feature only because of ABI concerns seems silly – you could just as easily pick on templates, inheritance, etc.

    I think it's a lot more productive to use C++ inside the project, and just stick with C for the external interface, using 'extern "c"' and trapping any exceptions.  That seems a lot easier than cluttering all the core classes with error code checks, dealing with constructors that can't throw exceptions any more, etc.

    [The compiler would have to walk the stack somehow and see "Oh, wait, this function on the stack does not implement an exception handler, so I will call terminate." But the way most C++ implementations walk the stack is by having each function with a catch block register itself on a linked list of activation records. So every function that doesn't have exception handling would still have to register an exception handler so that the exception dispatch code can find it. You can't have the throw detect its caller at compile time because the caller isn't known until runtime. What happens when you throw across a function with no exception handler is that the frame is simply not seen in the search for a handler. It's not an explicit nop; it's an implicit one. It's like saying "People who don't sign up for the newsletter don't receive information from us (it's a nop). We should notify our communications director when we send out a newsletter and there are people who haven't signed up." (And yes, you need to make sure no C++-ness escapes your language boundary. But most of them are easy to contain because they aren't possible in the first place. You don't pass classes as method parameters across language boundaries because there's no way to express them in a language-independent way. But it is very easy to accidentally throw an exception across language boundaries. See all the people asking questions about why their C++ exception thrown across a wndproc doesn't work!) -Raymond]
  20. Klimax says:

    I was under impression that compiler/libraries would use WinAPI SEH instead of C++ exception handling if disabled. (similar syntax too)

  21. GregM says:

    According to a discussion that a group of us had the other day, the reason that Google originally didn't allow exceptions was that they were too expensive.  That is now generally no longer the case, but they have a multi-million line codebase that is not exception-safe, so they can't just start using exceptions in it without having to go through and update everything to be exception-safe.

  22. "But it is very easy to accidentally throw an exception across language boundaries. See all the people asking questions about why their C++ exception thrown across a wndproc doesn't work!"

    Too true!  LOL…  Of course, eliminating exceptions project-wide brings new complications.  For example, how to handle failing constructors?  Do you just construct a "zombie" class that can't do anything?  Do you require that constructors do nothing, and have an "Initialize" function instead (e.g. Google style guide)?  The entire thing feels like an ugly hack.  Either way, now you have to remember to check the state of a class on entry of every member function:

    HRESULT Class::Member() { if (!initialized) { return E_FAIL; } /* snip */ }

    If it's a simple class that won't need to require/support reinitialization later, I find it easiest just to perform initialization in the constructor and throw if it fails.  Then the rest of the class can always assume that it has been correctly initialized (i.e. the "if (!initialized)" check can be removed).

    And what about STL and boost?  Do you just ignore all that and reinvent the wheel with something that doesn't use exceptions?  (e.g. vector::push_back might have to reallocate heap memory, which could fail – throwing a bad_alloc exception.  But if you don't have exceptions, what's it supposed to do?  Some vector constructors might throw, too.  Do we make our own custom vector STL container that requires an Initialize function call before using it?  What about STL class copy constructors / assignment operators, which call copy constructors / assignment operators on contained objects – what if the copy constructor fails?  Forget the STL; how will *you* handle errors in your copy constructors and assignment operators?)

    I guess everything is a trade-off.  Personally, I'd rather use exceptions, rather than deal with reinventing the STL, etc.  Trying to rip out exceptions completely feels too much like breaking the entire language.

  23. Matt says:

    @JamesJohnson

    >> "For example, how to handle failing constructors?"

    In this paradigm, constructors are never allowed to fail (although new Object() can still fail in the new() due to OOM).

    If your object is complicated and might legitimately throw (e.g. CMyAwesomeFileStream), you have an Init() that is allowed to return a HRESULT, or a static constructor, e.g.:

    CMyAwesomeFileStream fs;

    HRESULT hr = fs.OpenRead("C:/foo.txt"); // effectively Init

    if(!SUCCEEDED(hr)) …

    or

    CMyAwesomeFileStream* fs = NULL;

    HRESULT hr = CAwesomeFileStreamFactory.CreateFileStream(&fs, "C:/foo.txt");

    if(!SUCCEEDED(hr)) …

Comments are closed.

Skip to main content