jirentabu / crashrpt

Automatically exported from code.google.com/p/crashrpt
0 stars 0 forks source link

Using Vectored Exception Handling #30

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
For both the documentation
(http://crashrpt.sourceforge.net/docs/html/exception_handling.html) and the
latest code I see all you do for setting up the exception handler is
SetUnhandledExceptionFilter(). I did some research about exception handling
these days and came across the Vectored Exception Handling
(http://msdn.microsoft.com/en-us/library/ms681420%28v=VS.85%29.aspx). I'm
not quite aware about the difference between the two sets of APIs, but
seems the VEH is more robust and compatible if available, for example you
can remove the handler when DLL is detached from the host process. If there
is no compelling reasons, maybe you can consider adopting VEH in the future
versions.

Original issue reported on code.google.com by crendk...@gmail.com on 9 Apr 2010 at 6:53

GoogleCodeExporter commented 9 years ago
Ok, I'll try to use it in a future version.

An advantage of VEH is an ability to chain exception handlers, so if somebody
installs exception handler above ours, we still can intercept the exception.

The disadvantage is that VEH is available in WinXP and later. So the presence of
SetVectoredExceptionHandler() function should be checked at run-time.

Original comment by zexspect...@gmail.com on 9 Apr 2010 at 8:36

GoogleCodeExporter commented 9 years ago
After reviewing VEH some more time, I think it is problematic to use VEH 
instead of
SetUnhandledExceptionFilter(). 

Vectored exception handling is suitable when you need to monitor _ALL_ 
exceptions,
like a debugger does. But how would CrashRpt decide which exception to handle 
and
which to skip? In client's code, some exceptions may be intentionally guarded by
__try{}__except(){}, and handling such exceptions in VEH and not passing it to
frame-based SEH handler, we may introduce bugs into application logics.

SetUnhandledExceptionFilter() is more suitable, because it is the top-level SEH
handler. If nobody handles the exception, top-level SEH handler is called and 
you
don't need to decide if you should skip the exception or not.

Original comment by zexspect...@gmail.com on 9 Apr 2010 at 11:16

GoogleCodeExporter commented 9 years ago
I never use try catch or __try __except in my code, therefore did not notice the
difference. I think you are correct at this point. The VEH is always executed 
before
the __except handler, no matter what "First" parameter is specified. Nor there 
seems
no way to get the chain of all the handlers.

However, VEH also has advantages:

You do not have to worry whether other modules would overwrite your handler
registration. In my code, I call SetUnhandledExceptionFilter in a DLL (to create
minidump when crash), and load it into my exe using LoadLibrary in wWinMain(). 
The
exception handler in DLL is never called. When I call 
SetUnhandledExceptionFilter
when the DLL is being unloaded, I noticed that the handler has been changed to
__CxxUnhandledExceptionFilter (likely to be set by CRT). The same issue is also
stated in the crashrpt FAQ. If I switch to VEH, everything works fine. Because 
of
this, it seems I cannot use crashrpt in my DLL neither, unless the DLL is 
delayed
loaded or I can get rid of the __CxxUnhandledExceptionFilter (do you have any 
idea?
Many thanks!).

As you mentioned, even if the exception is handled in the exe, the handler in 
DLL
will still be called. to work around this, I check the exception address in the
handler. If the exception happens between the DLL base and DLL base + DLL image 
size,
its our exception and handle it. Otherwise, directly return 
EXCEPTION_CONTINUE_SEARCH.

Original comment by crendk...@gmail.com on 9 Apr 2010 at 1:15

GoogleCodeExporter commented 9 years ago
Seems __CxxUnhandledExceptionFilter is registered by every DllMainCRTStartup, 
which
means even if SetUnhandledExceptionFilter is called in the exe's main function, 
if
there is any delay load dll, it is possible to overwrite the handler again. It 
is
quite confusion why __CxxUnhandledExceptionFilter takes over the handler all the
time, even the current unhandled exception filter is not NULL.

Maybe I can hook SetUnhandledExceptionFilter() after my handler is successfully
registered, so that other DLL will never overwrite.

Original comment by crendk...@gmail.com on 9 Apr 2010 at 1:33

GoogleCodeExporter commented 9 years ago
Usage of VEH is problematic, because it requires to manually filter exceptions. 
I
currently do not plan to use VEH in CrashRpt.

Original comment by zexspect...@gmail.com on 14 Apr 2010 at 10:35