Current version

v1.10.4 (stable)

Navigation

Main page
Archived news
Downloads
Documentation
   Capture
   Compiling
   Processing
   Crashes
Features
Filters
Plugin SDK
Knowledge base
Contact info
 
Other projects
   Altirra

Archives

Blog Archive

An absolutely brilliant way to make sure buggy programs don't get fixed

I just spent the last hour or so trying to figure out why the newly added 64-bit configuration of my program didn't run, only to discover it was because Visual Studio happily linked in all *.manifest files it found in the project even though I don't see any docs or options mentioning this, and the manifest command line in project settings doesn't show it. Okay, we can deal with that, just set "exclude from build" and hope it works. Run it from the command line, and, yup, it now launches.

Crash. Oh well, the first launch never works anyway, probably a simple 64-bit porting issue. Visual Studio JIT dialog comes up, choose to debug.

To my horror, I then saw this dialog (this is Windows 7, btw):

[Program Compatibility Assistant]

Uh, WTF? I'm trying to debug the program, why would I want to enable a compatibility mode for it? And where's the cancel button??

I spent the next ten minutes trying to find out how to check a program's status or remove it from the compatibility list, and I couldn't find one. After a bit of spelunking in the Registry, I was horrified to find this:

[PCA registry entry]

A bit of explanation: user callbacks happen whenever the kernel-mode OS code needs to call back into the program in user space. The most common case of this is a window procedure, where the window manager running in kernel mode issues a callback to invoke the program's winproc code. I can't find concrete information on it, but what this mode appears to do is eat exceptions thrown from the user code, as if a try/catch with an empty handler were wrapped around it. And sure enough, when I ran the program, it didn't crash. It simply proceeded to silently not work instead. I could at least reproduce the crash under the debugger, but no longer out of it.

If I get all of this correctly, I find this to be a terrible design. The reason for the PCA is understandable, but the execution is lousy. Not only is there no apparent way to tell Windows not to apply a compatibility mode, but it also permanently enables that behavior for the program. Not even deleting and recreating the program will work, because the path is now embedded in the Registry. There does appear to be a supported way to disable the PCA (Group Policy), but it looks like the Registry Editor is the only way to remove a program entry. This has a number of bad implications for developers, because it means that you will only see the bug once, your QA and beta testers will only see the bug once, and after you've shipped a buggy app that you think is OK, your end users will see the bug once. The end result is that programmers keep shipping broken code, because the bugs are being masked.

Comments

This blog was originally open for comments when this entry was first posted, but was later closed and then removed due to spam and after a migration away from the original blog software. Unfortunately, it would have been a lot of work to reformat the comments to republish them. The author thanks everyone who posted comments and added to the discussion.