I'm dealing with a function and a subfunction, the subfunction being called within the function. Both have a __try .. __except
-clause, and I'd like to see the general exception handling in case of the function, and the specific one in case of the subfunction, in other words:
int function(){
__try{
do_something();
return subfunction();
} __except (Exception_Execute_Handler_Something()){
show("general exception");
}
int subfunction(){
__try{
return do_something_else();
} __except (Exception_Execute_Handler_Something_Else()){
show("specific case");
}
In this case:
When do_something()
goes wrong, I see "general exception".
When do_something_else()
goes wrong, I also see "general exception", which is not what I want.
What I want is:
When do_something()
goes wrong, I want to see "general exception.
When do_something_else()
goes wrong, I want to see "specific case".
Edit after Ben Voight's remark
There indeed is an exception filter, and this is currently checking the exception code for deciding whether or not to continue, as you can see here:
if (Exception->ExceptionCode == STATUS_ACCESS_VIOLATION)
return EXCEPTION_CONTINUE_SEARCH;
I have, however, no knowledge at all in the structure and/or content of ExceptionRecord
and ContextRecord
, the two input parameters of the exception handling. Hereby I give an example of what those parameters look like in my particular case:
Exception record:
- ExceptionRecord 0x0eecdec8 {ExceptionCode=3221225620 ExceptionFlags=0 ExceptionRecord=0x00000000 <NULL> ...} _EXCEPTION_RECORD *
ExceptionCode 3221225620 unsigned long // I guess this means division by zero
ExceptionFlags 0 unsigned long
+ ExceptionRecord 0x00000000 <NULL> _EXCEPTION_RECORD *
ExceptionAddress 0x002c1993 {<Application>.exe!CClass::Main_Method(CInputClass & params), Line 46} void *
NumberParameters 0 unsigned long
+ ExceptionInformation 0x0eecdedc {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} unsigned long[15]
ContextRecord:
- ContextRecord 0x0eecdf18 {ContextFlags=65543 Dr0=0 Dr1=0 ...} _CONTEXT *
ContextFlags 65543 unsigned long
Dr0 0 unsigned long
Dr1 0 unsigned long
Dr2 0 unsigned long
Dr3 0 unsigned long
Dr6 0 unsigned long
Dr7 0 unsigned long
- FloatSave {ControlWord=0 StatusWord=0 TagWord=0 ...} _FLOATING_SAVE_AREA
ControlWord 0 unsigned long
StatusWord 0 unsigned long
TagWord 0 unsigned long
ErrorOffset 0 unsigned long
ErrorSelector 0 unsigned long
DataOffset 0 unsigned long
DataSelector 0 unsigned long
+ RegisterArea 0x0eecdf50 "" unsigned char[80] // all are zero
Spare0 0 unsigned long
SegGs 43 unsigned long
SegFs 83 unsigned long
SegEs 43 unsigned long
SegDs 43 unsigned long
Edi 80923496 unsigned long
Esi 250405956 unsigned long
Ebx 0 unsigned long
Edx 0 unsigned long
Ecx 0 unsigned long
Eax 1 unsigned long
Ebp 250405884 unsigned long
Eip 2890131 unsigned long
SegCs 35 unsigned long
EFlags 66118 unsigned long
Esp 250405880 unsigned long
SegSs 43 unsigned long
+ ExtendedRegisters 0x0eecdfe4 "\x2 \x1" unsigned char[512] // at first sight, not readable
Now my question has turned into:
In case I'm already inside another __try..__except
clause, I'd return EXCEPTION_CONTINUE_SEARCH
.
Does anybody know which of the mentioned ExceptionRecord
or ContextRecord
properties I can use for determining whether or not I am already inside another __try..__except
clause?
New edit after again some more information
I've just found EXCEPTION_DISPOSITION
, present in C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Tools\MSVC\14.16.27023\include\excpt.h
. This contains the function _except_handler()
, which returns an EXCEPTION_DISPOSITION
enum, which can be ExceptionNestedException
(I believe this is the one I'm looking for).
So now the question turns into:
What parameters do I need to fill in in the function
_except_handler()
in order to know if I'm dealing with a nested exception (or does somebody know an easier way to get this done)?
Your code as written does not compile. Instead of:
__except { ... }
you need:
__except (EXCEPTION_EXECUTE_HANDLER) { ... }
Then it works as desired.