The unhandled exception filter is the responsibility of the process; don’t change it without permission


A customer developed an Office add-in and wanted to intercept all unhandled exceptions so that they could collect crash dumps, capture stack traces, and so on. To do this, they used the Set­Unhandled­Exception­Filter function to register their custom unhandled exception handler to capture crash dumps and stack traces.

The customer reported that this technique was successful in earlier versions of Office, but stopped working starting in Office 2013. (They didn't test Office 2010.) Their custom unhandled exception handler is no longer being called.

The customer wanted to know if there were any known circumstances where the Set­Unhandled­Exception­Filter function would stop working, and what workarounds were available, even if it means abandoning their current strategy and getting their crash dumps some other way.

The unhandled exception filter is a process-wide resource, and therefore the process is the one who makes the decision what unhandled exception filter they want. A DLL is a guest in the host process, and common courtesy says that guests don't cancel the homeowner's insurance policy and replace it with their own.

Besides, imagine what would happen if two plug-ins wanted to replace the unhandled exception filter. (Bonus: And then one of those plug-ins was unloaded.)

The Office team discovered that large numbers of add-ins were (either intentionally or inadvertently) corrupting the process-wide unhandled exception filter. This meant that crashes were no longer being routed through Office's own unhandled exception filter. Not only were none of the crashes in Office being reported through Windows Error Reporting, users were losing data because Office's custom unhandled exception filter was not getting a chance to attempt document recovery before the process finally went away.

To work around rogue DLLs replacing the unhandled exception filter, Office detours the Set­Unhandled­Exception­Filter function.

This answer from Office developer support confirms the above discussion and further suggests a workaround: Register your plug-in with Windows Error Reporting. Microsoft's back-end error reporting service (known as Watson, not the same as Dr. Watson). All the crashes received by the Watson service are analyzed, and if the analysis concludes that your plug-in was responsible for the problem, the crash dump will be made available to you.

Comments (12)
  1. kantos says:

    If the addin developer was doing a .NET addin properly they would have their own app-domain and would be able to do this without issue within the CLR portion of their addin because this is appdomain specific in that case. Of Course this requires you find the code to do that which has long since been lost in the dark recesses of the internet.

  2. Luke says:

    > To work around rogue DLLs replacing the unhandled exception filter, Office detours the Set­Unhandled­Exception­Filter function.

    It’s “what if two programs did this?” all the way down.

    1. There is no lower turtle. The process controls its unhandled exception filter.

      1. Joshua says:

        I had a plan against a bad A/V to undetour a function. It’s tricky on 64 bit and I’m glad I never used it.

    2. Antonio Rodríguez says:

      No, Luke. It’s more like “my house, my rules”. I may have invited you to come over for a beer, but you aren’t allowed to put your feet on the couch or peek into the dressing room.

    3. Pierre B. says:

      > To work around rogue DLLs replacing the unhandled exception filter, Office detours the Set­Unhandled­Exception­Filter function.

      To work around this, launch another process, find the offset from teh base location to SetUnHandledExceptionFilter, send the result back to the main process, patch back the true entry point of the functions…

      Then Office adds a timer to re-patch, so the DLL uses a shorter timer and detour CreateTimer. Then… well, long story short, that’s why Office now ships with a daughterboard with a separate CPU that you plug your CPU into.

  3. Mason Wheeler says:

    > Besides, imagine what would happen if two plug-ins wanted to replace the unhandled exception filter.

    They would both add a handler to the relevant event and there would be no problem? ;-)

  4. jon says:

    Windows error reporting seems to constantly take over and prevent our unhandled exception filter from being called…

  5. Gee Law says:

    No wonder why the new Office add-in platform is built on JavaScript — it provides a big diaper for all the sh*ts the developers have created, which can be avoided in the first place. (Yes, I know diapers are not for sh*ts.)

  6. sean says:

    Due to GDPR, addin developers are no longer able to get crash dumps from Windows Error Reporting except for processes that the addin owns — which typically isn’t the addin host.

    1. Patrick Van Cauteren says:

      Raymond, I completely agree. If a process decides to set the UnhandledExceptionFilter, everyone else should keep their hands of it. For developers using Oracle: set the DIAG_SIGHANDLER_ENABLED=FALSE configuration line in SQLNET.ORA, otherwise Oracle will also overrule the UnhandledExceptionFilter.
      By the way, it looks like .Net is overruling our UnhandledExceptionFilter as well. Shouldn’t .Net keep its hands of it as well?

  7. Yuhong Bao says:

    “(Bonus: And then one of those plug-ins was unloaded.)”
    Well known security problem BTW.

Comments are closed.

Skip to main content