1

TL;DR

(Visual Studio 2019, Windows 10 (so far tested on 1809LTSC, because this is my dev machine)

  • We have an out-of-process COM server
  • We set COMGLB_EXCEPTION_DONOT_HANDLE_ANY
  • "Fatal" SEH exceptions are handled OK.
  • "Non-Fatal" SEH exceptions, among these C++ excpetions, are randomly swallowed or handled by the COM/RPC runtime stack.

Does COMGLB_EXCEPTION_DONOT_HANDLE _ANY work reliably? Are there any additional settings?

Neccessary Background

When using COM, the RPC layer will catch (and possibly swallow) all Structured SEH Exceptions (which include C++ exceptions). Raymond explains this very well:

Historically, COM placed a giant try/except around your server’s methods. If your server encountered what would normally be an unhandled exception, the giant try/except would catch it and turn it into the error RPC_E_SERVERFAULT. It then marked the exception as handled, so that the server remained running ... Mind you, this was actually a disservice

Now there is a supposed solution, namely IGlobalOptions with setting COMGLB_EXCEPTION_DONOT_HANDLE_ANY.

This is supposed to (to quote The Old New):

... then go ahead and let the process crash.” In Windows 7, you can ask for the even stronger COMGLB_EXCEPTION_DONOT_HANDLE_ANY, which means “Don’t even try to catch ‘nonfatal’ exceptions.”

You can even find this recommendation in the docs:

It's important for applications that detect crashes and other exceptions that might be generated while executing inbound COM calls, ... to set COMGLB_EXCEPTION_HANDLING to COMGLB_EXCEPTION_DONOT_HANDLE to disable COM behavior of catching exceptions.

And the option is explained as:

COMGLB_EXCEPTION_DONOT_HANDLE_ANY:

  • When set and a fatal exception occurs in a COM method, this causes the COM runtime to not handle the exception. (caveat A)
  • When set and a non-fatal exception occurs in a COM method, this causes the COM runtime to create a Windows Error Reporting (WER) dump and terminate the process. Supported in Windows 7 and later. (caveat B)

And here's the thing

Neither of the above two statements is really accurate, but specifically for any non fatal exception, which C++ exceptions are, we get random behavior:

I have set up a simple client / server COM Test Program in VS2019 and intentionally generate an unhandled C++ exception: There are two modes at runtime, seemingly at random:

  • Server is terminated by the COM/RPC stack and we get an ID 1000 entry in the event log with the exceptioncode 0xe06d7363 (and a WER dump is written). The client gets 0x800706BE HRESULT in this case.
    • This is the advertised behavior.
  • Starting the client -> server a second (or third, ...) time, the C++ Exception DOES NOT terminate the server, and the client gets 0xe06d7363 as HRESULT for its server call. No event log entry written!

For those "fatal" SEH exceptions the termination happens reliably; but not for the non-fatal ones.

What is going on here?

Martin Ba
  • 37,187
  • 33
  • 183
  • 337
  • 1
    I don't reproduce. For me the option works as expected, each time you start a server configured with COMGLB_EXCEPTION_DONOT_HANDLE_ANY and throw for example a C++ exception (0xe06d7363), the server terminates (and the client receives 0x800706BE). Note depending on your local config, the server throwing may start a debugger or other stuff instead of terminating immediatly. Or please provide a complete reproduction example. IGlobalOptions must be set right after server's CoInitialize call. – Simon Mourier Jun 01 '22 at 12:11
  • @SimonMourier - thanks for trying. Yeah, maybe it is a environmental issue. I don't see any debugger attaching - the server just continues to run normally. But given it's flaky on my side, it would appear natural to assume that there are cases like yours where it's simply working. The purpose of the question really is to gauge whether I'm missing something obvious with the setup. – Martin Ba Jun 01 '22 at 12:57

0 Answers0