A customer reported that their system crashed with bugcheck code 0xEF: CRITICAL_
The team scoured their code for all uses of that RAII type and couldn’t find any place where they could possibly be using it incorrectly.
Eventually, the team discovered that a third party anti-malware application had injected itself into the RPCSS service and was detouring some functions.¹ And for some reason, the detour was unhappy, but instead of failing the call, it raised a structured exception.
This structured exception was caught by the RPC equivalent of the giant try/catch that COM wraps around every server method. For RPC, this wrapper goes by the name RpcExceptionFilter
. The exception was raised from their detour and it so happens that the exception they raised is not one that the RpcExceptionFilter
function deems to be noteworthy, so the RpcExceptionFilter
function swallows the exception and returns an RPC failure to the client.
As I noted, this structured exception bypasses C++ destructors.
And that’s why the RAII class was not working. The code wasn’t holding it wrong. Rather, the third party code broke the rules.
Now, the third party code had this problem all along: The rogue exception caused an entire RPC call to become abandoned mid-stream, resulting in lots of leaks and missing cleanup. What changed is that there’s new code in the RPCSS service that was counting on the cleanup to avoid a crash.
This particular anti-malware program must be somewhat popular because the problem recurs about once or twice a year with a different customer each time. This is the bitter spot² in bug frequency, because it’s not frequent enough that the problem remains on your mind whenever you get a mystery crash so you can open the discussion with the customer by saying, “Okay, before I spend too much time on this, can you tell me if you recently installed or reconfigured Contoso anti-malware?” On the other hand, the issue is frequent enough that it consumes a lot of time and effort to gather crash dumps and eventually realize that it’s that Contoso anti-malware problem again.
¹ Windows does not support detouring the operating system. This anti-malware software is doing unsupported things, but good luck explaining that to their customers.
² The bitter spot is the opposite of the sweet spot. Or is the opposite of the sweet spot the salty spot? The sour spot? Maybe it’s all of them. When you find yourself in this spot, you are probably going to be sour, bitter and probably a little salty.
You left out the umami spot.
Fighting games seem to have settled on “sour spot”.
It could help to get a short wpr recording of the machine which collects all loaded modules besides a memory dump as default action. I had my own share of AV induced issues and did write https://github.com/Siemens-Healthineers/ETWAnalyzer to be able to quickly query all known AV vendors in the stacks. With proper stacktags one can quickly find out if the slowness of an application comes from SmartScreen, Mc Affee or any other AV vendor. I...
Yeah, reminds me of the full week I lost, around the 1996 time frame, when Microsoft IT mandated a particular anti-virus software (InocuLAN? I don't recall for sure which third-party software it was) that wound up corrupting input files during compilation, generating compile-time errors that didn't seem to correspond to any actual problem with the code. I wasted that whole week doing all kinds of different things to try to track down the problem in...
When I worked at Prime Computer, we had an automated dump-analysis tool that had rules about what things in a crash dump were clues to known crashes. For example, if a particular routine crashed, and the third parameter was invalid, it was a known crashing bug (fixed in a later release). Doesn’t Microsoft have something similar?
Windows Error Reporting, as I recall, (used to) categorize defects into buckets, where ideally each bucket would refer to the same core issue. Microspeak: Bucket bugs, bucket spray, bug spray, and failure shift goes over some of the challenges and illustrates the outcomes when things are less than ideal.
The first time I read this, I missed the “anti-” in “anti-malware application.” It made a lot more sense that way.
Anti-malware software is the most common type of malware after all.
Bonus chatter: Rust considers RAII leaks (which Rust supports officially through e. g. ) to be safe. This is normally OK, until someone tries to rely on destructors being run to guarantee safety, like did (crates.io thread-scoped).
Rust reconciled them with a new continuation-passing style API (), which by design prevents ting the join guard.
(Not that it would help the case of an unhandled structured exception.)
Bonus bonus chatter: Doing anything that involves...
When helping someone with a weirdly behaving program, in the old days #1 advice used to be “Upgrade your video driver” but today I always start with “Do you have any 3rd-party antivirus program installed” because sadly they are often the culprit.
Also thank you for making me laugh: “… The code wasn’t holding it wrong. . “” 🙂