[PATCH v2] vcruntime140_1: Terminate on noexcept function trying to propagate exception.
Daniel Lehman
dlehman25 at gmail.com
Wed Sep 30 21:14:56 CDT 2020
Signed-off-by: Daniel Lehman <dlehman25 at gmail.com>
---
v2: handle nested case
this should print 0x42:
wine64 tosend.exe
these should terminate():
wine64 tosend.exe 1
wine64 tosend.exe 1 1
wine64 tosend.exe 1 1 1
/* cl /EHsc /MD noexcept.cpp */
void do_throw(void) { throw int(0x42); }
void crash_without_tries(void) noexcept { do_throw(); }
void crash_with_tries(void) noexcept
{
try { do_throw(); } catch (float e) { /* bogus */ }
}
void crash_nested(void) noexcept
{
try {
try { throw 1; }
catch (int e) { throw; }
}
catch (float f) { /* bogus */ }
}
void works(void) noexcept
{
try { do_throw(); } catch (int e) { printf("0x%x\n", e); }
}
void works_nested(void) noexcept
{
try {
try { throw 1; }
catch (int e) { throw; }
}
catch (...) {
}
}
void works_nested2(void) noexcept
{
try {
try {
try { throw 1; }
catch (int e) { throw; }
}
catch (int e) { throw; }
}
catch (...) {
}
}
int main(int argc, char **argv)
{
try
{
switch (argc)
{
case 4: crash_nested(); break;
case 3: crash_without_tries(); break;
case 2: crash_with_tries(); break;
default:
works();
works_nested();
works_nested2();
break;
}
}
catch (...)
{
printf("%s: should not be printed\n", __FUNCTION__);
}
return 0;
}
---
dlls/vcruntime140_1/except_x86_64.c | 90 ++++++++++++++++-------------
1 file changed, 49 insertions(+), 41 deletions(-)
diff --git a/dlls/vcruntime140_1/except_x86_64.c b/dlls/vcruntime140_1/except_x86_64.c
index f66ae43721f..341f26a20c2 100644
--- a/dlls/vcruntime140_1/except_x86_64.c
+++ b/dlls/vcruntime140_1/except_x86_64.c
@@ -683,56 +683,64 @@ static DWORD cxx_frame_handler4(EXCEPTION_RECORD *rec, ULONG64 frame,
cxx_local_unwind4(orig_frame, dispatch, descr, trylevel, last_level);
return ExceptionContinueSearch;
}
- if (!descr->tryblock_map) return ExceptionContinueSearch;
-
- if (rec->ExceptionCode == CXX_EXCEPTION)
+ if (descr->tryblock_map)
{
- if (!rec->ExceptionInformation[1] && !rec->ExceptionInformation[2])
- {
- TRACE("rethrow detected.\n");
- *rec = *(EXCEPTION_RECORD*)*__current_exception();
- }
-
- exc_type = (cxx_exception_type *)rec->ExceptionInformation[2];
-
- if (TRACE_ON(seh))
+ if (rec->ExceptionCode == CXX_EXCEPTION)
{
- TRACE("handling C++ exception rec %p frame %lx descr %p\n", rec, frame, descr);
- dump_exception_type(exc_type, rec->ExceptionInformation[3]);
- }
- }
- else
- {
- _se_translator_function se_translator = get_se_translator();
-
- exc_type = NULL;
- TRACE("handling C exception code %x rec %p frame %lx descr %p\n",
- rec->ExceptionCode, rec, frame, descr);
+ if (!rec->ExceptionInformation[1] && !rec->ExceptionInformation[2])
+ {
+ TRACE("rethrow detected.\n");
+ *rec = *(EXCEPTION_RECORD*)*__current_exception();
+ }
- if (se_translator) {
- EXCEPTION_POINTERS except_ptrs;
- se_translator_ctx ctx;
+ exc_type = (cxx_exception_type *)rec->ExceptionInformation[2];
- ctx.dest_frame = frame;
- ctx.orig_frame = orig_frame;
- ctx.seh_rec = rec;
- ctx.dispatch = dispatch;
- ctx.descr = descr;
- ctx.trylevel = trylevel;
- __TRY
+ if (TRACE_ON(seh))
{
- except_ptrs.ExceptionRecord = rec;
- except_ptrs.ContextRecord = context;
- se_translator(rec->ExceptionCode, &except_ptrs);
+ TRACE("handling C++ exception rec %p frame %lx descr %p\n", rec, frame, descr);
+ dump_exception_type(exc_type, rec->ExceptionInformation[3]);
}
- __EXCEPT_CTX(se_translation_filter, &ctx)
- {
+ }
+ else
+ {
+ _se_translator_function se_translator = get_se_translator();
+
+ exc_type = NULL;
+ TRACE("handling C exception code %x rec %p frame %lx descr %p\n",
+ rec->ExceptionCode, rec, frame, descr);
+
+ if (se_translator) {
+ EXCEPTION_POINTERS except_ptrs;
+ se_translator_ctx ctx;
+
+ ctx.dest_frame = frame;
+ ctx.orig_frame = orig_frame;
+ ctx.seh_rec = rec;
+ ctx.dispatch = dispatch;
+ ctx.descr = descr;
+ ctx.trylevel = trylevel;
+ __TRY
+ {
+ except_ptrs.ExceptionRecord = rec;
+ except_ptrs.ContextRecord = context;
+ se_translator(rec->ExceptionCode, &except_ptrs);
+ }
+ __EXCEPT_CTX(se_translation_filter, &ctx)
+ {
+ }
+ __ENDTRY
}
- __ENDTRY
}
+
+ find_catch_block4(rec, context, NULL, frame, dispatch, descr, exc_type, orig_frame, trylevel);
}
- find_catch_block4(rec, context, NULL, frame, dispatch, descr, exc_type, orig_frame, trylevel);
+ if ((descr->header & FUNC_DESCR_NO_EXCEPT) &&
+ !(descr->header & FUNC_DESCR_IS_CATCH))
+ {
+ ERR("noexcept function propagating exception\n");
+ terminate();
+ }
return ExceptionContinueSearch;
}
@@ -759,7 +767,7 @@ EXCEPTION_DISPOSITION __cdecl __CxxFrameHandler4(EXCEPTION_RECORD *rec,
return ExceptionContinueSearch; /* handle only c++ exceptions */
if (descr.header & ~(FUNC_DESCR_IS_CATCH | FUNC_DESCR_UNWIND_MAP |
- FUNC_DESCR_TRYBLOCK_MAP | FUNC_DESCR_EHS))
+ FUNC_DESCR_TRYBLOCK_MAP | FUNC_DESCR_EHS | FUNC_DESCR_NO_EXCEPT))
{
FIXME("unsupported flags: %x\n", descr.header);
return ExceptionContinueSearch;
--
2.25.1
More information about the wine-devel
mailing list