Я имею дело с функцией и подфункцией, подфункция вызывается внутри функции.Оба имеют __try .. __except
-класс, и я хотел бы видеть общую обработку исключений в случае функции и конкретную в случае подфункции, другими словами:
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в этом случае:
Когда do_something()
идет не так, я вижу «общее исключение».
Когда do_something_else()
идет не так, я также вижу «общее исключение», а это не то, что я хочу.
Что я хочу:
Когда do_something()
идет не так, я хочу видеть «общее исключение».
Когда do_something_else()
идет не так, я хочу видеть «конкретный случай».
Редактировать после замечания Бена Войта
Действительно, существует фильтр исключений, и в настоящее время проверяется код исключения для принятия решения о том, продолжать или нет, как вы можете видеть здесь:
if (Exception->ExceptionCode == STATUS_ACCESS_VIOLATION)
return EXCEPTION_CONTINUE_SEARCH;
Однако я совершенно ничего не знаю о структуре и / или содержании ExceptionRecord
и ContextRecord
, двух входных параметров обработки исключений. Приведу пример того, как эти параметры выглядят вмой конкретный случай:
Исключительная запись:
- 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
Теперь мой вопрос превратился в:
Если я уже нахожусь в другом предложении __try..__except
, я бы return EXCEPTION_CONTINUE_SEARCH
.
Кто-нибудь знает, какое из упомянутых свойств ExceptionRecord
или ContextRecord
я могу использовать для определения, нахожусь ли я уже в другом предложении __try..__except
?
Новое редактирование послееще немного информации
Я только что нашел EXCEPTION_DISPOSITION
, присутствует в C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Tools\MSVC\14.16.27023\include\excpt.h
.Он содержит функцию _except_handler()
, которая возвращает перечисление EXCEPTION_DISPOSITION
, которое может быть ExceptionNestedException
(я считаю, что это то, что я ищу).
Так что теперь вопрос превращается в:
Какие параметры мне нужно заполнить в функции _except_handler()
, чтобы узнать, имею ли я дело с вложенным исключением (или кто-нибудь знает более простой способ сделать это)?