Search

A proposal to make Dr.Watson invocation configurable by Paul Shmakov

Closed
as Not Reproducible Help for as Not Reproducible

17
Sign in to vote
0
Sign in to vote
Sign in
to vote
Type: Suggestion
ID: 101337
Opened: 3/16/2006 1:58:31 AM
Access Restriction: Public
1
Workaround(s)
Visual C++ 2005 CRT library tends to call Dr.Watson directly in some emergency cases, ignoring user-defined unhandled exception filter. We need an ability to configure this behavior.

Rationale

When any of CRT invariants are violated (invalid arguments passed, buffer overrun detected, etc.) CRT needs to report somehow about that violation. VC++ 2005 uses the following strategy:
1. Display (optionally) a message box with error description.
2. Invoke Dr.Watson to create crash dump.

(All this code is located in abort.c, gs_report.c, and invarg.c files).

The concern and question is about the second step - an invocation of Dr.Watson.

There's no "good" way to replace Dr.Watson's reporting with user-defined error reporting procedure. Some applications need to perform some additional actions, such as writing their own crash dumps, logging error information, etc.

But VC++ 2005 CRT forces us to use Dr.Watson - all mentioned above files use the following trick to invoke Dr.Watson:

        /* Make sure any filter already in place is deleted. */
        SetUnhandledExceptionFilter(NULL);

        UnhandledExceptionFilter(&ExceptionPointers);

CRT removes any currently installed exception filter with SetUnhandledExceptionFilter(NULL) and produce an unhandled exception to invoke Dr.Watson.

QUESTION: Why there's no way to change this behavior?

We need an ability to replace Dr.Watson invocation with our own procedure OR to register a callback that will be fired before Dr.Watson invocation.

Workarounds

1. _set_abort_behavior, signal(SIGABRT, ...), and _set_invalid_parameter_handler(...) functions allow to intercept just *several* cases. But there're a lot of checks in CRT code that pass around and invoke Dr.Watson directly (just search for "_invoke_watson").

2. API hooking technique to intercept SetUnhandledExceptionFilter function to prevent user-defined filter to be replaced. It couldn’t be considered as a good way in many applications.
Details (expand)
Product Language
English
Version
Visual Studio 2005
Category
Libraries
Operating System
Windows Server 2003
Operating System Language
US English
Proposed Solution
1. An ability to disable "SetUnhandledExceptionFilter(NULL)" statement in abort.c, gs_report.c, and invarg.c files using, for example, _set_abort_behavior(0, _INVOKE_WATSON) call or something like this.

OR

2. An ability to register a callback function that will be fired just before an invocation of Dr.Watson.
Benefits
Improved Reliability
Improved Administration
Other Benefits
Improved Administration
File Attachments
0 attachments
Sign in to post a comment.
Posted by Microsoft on 3/21/2006 at 10:22 PM
There are several separate situations here

One is when we have detected a buffer overrun (/GS failure). For security reasons in this case, we directly call the UnhandledExceptionFilter. We removed the mechanism that VC7 had to intercept these because it represented a real vulnerability. This is not going to change.

Another is when we detect an invalid parameter before a bad situation occurs. You can use _set_invalid_parameter_handler to influence these errors and intercept what happens.

A third are other abnormal terminations (purecall, unexpected, etc). These generally have their own handlers that you can set (_set_purecall, _set_terminate, _set_unexpected). These exist only in cases where we consider it safe to do so.

If there's a specific case that I've not covered above where you'd like to be able to intercept but cannot, please open a specific suggestion item for that one. But we did review all the places we added _invoke_watson.

Aside from the /GS case (where we do have no interception point, deliberately, because the process is already unsafe), we do have intervention points. Since the watson code automatically collects a crash dump and writes to the event log, we think this design provides the appropriate balance of security and configurability.

In a last resort (not recommended) you can link to the static library where you can replace any function.

Martyn Lovell
Development Lead
Visual C++ Libraries
Posted by Terry Hardie on 9/11/2006 at 2:58 PM
Another way this could be done is with a compiler switch which could designate the Unhandled Exception Filter. This way there wouldn't be any security vulnerability at runtime (any more than there already is), and you'd get an unhandled exception handler for static constructors and destructors.
Posted by Claus Brod on 11/25/2006 at 12:21 AM
Very interesting idea! (I guess you actually meant a linker switch, right?)

What if someone has a couple of modules which are all compiled/linked with different unhandled exception filters? Which filter should win?
Posted by Jim Freeman on 3/24/2008 at 11:20 AM
_set_purecall, _set_terminate, _set_unexpected won't help when app DLLs use a static CRTL, as each app DLL would have to set handlers and point to the main app's handlers. Our app has no control over the source code to many DLLs the app uses.

Re "2. API hooking technique to intercept SetUnhandledExceptionFilter function to prevent user-defined filter to be replaced. It couldn’t be considered as a good way in many applications." Is this safe? I wonder if it will work on systems running products like the Cisco Security Agent that probably hooks this itself.