[PATCH] vcruntime140_1: Terminate on noexcept function trying to propagate exception.
Signed-off-by: Daniel Lehman <dlehman25(a)gmail.com> --- this should print 0x42: wine64 tosend.exe these should terminate(): wine64 tosend.exe 1 wine64 tosend.exe 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 works(void) noexcept { try { do_throw(); } catch (int e) { printf("0x%x\n", e); } } int main(int argc, char **argv) { try { switch (argc) { case 3: crash_without_tries(); break; case 2: crash_with_tries(); break; default: works(); break; } } catch (...) { printf("%s: should not be printed\n", __FUNCTION__); } return 0; } Signed-off-by: Daniel Lehman <dlehman25(a)gmail.com> --- dlls/vcruntime140_1/except_x86_64.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/dlls/vcruntime140_1/except_x86_64.c b/dlls/vcruntime140_1/except_x86_64.c index f66ae43721f..9d5757748d2 100644 --- a/dlls/vcruntime140_1/except_x86_64.c +++ b/dlls/vcruntime140_1/except_x86_64.c @@ -741,6 +741,7 @@ EXCEPTION_DISPOSITION __cdecl __CxxFrameHandler4(EXCEPTION_RECORD *rec, { cxx_function_descr descr; BYTE *p, *count, *count_end; + EXCEPTION_DISPOSITION ret; int trylevel; TRACE("%p %lx %p %p\n", rec, frame, context, dispatch); @@ -759,7 +760,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; @@ -789,7 +790,16 @@ EXCEPTION_DISPOSITION __cdecl __CxxFrameHandler4(EXCEPTION_RECORD *rec, if (!validate_cxx_function_descr4(&descr, dispatch)) return ExceptionContinueSearch; - return cxx_frame_handler4(rec, frame, context, dispatch, &descr, trylevel); + ret = cxx_frame_handler4(rec, frame, context, dispatch, &descr, trylevel); + if (descr.header & FUNC_DESCR_NO_EXCEPT && + !(rec->ExceptionFlags & (EH_UNWINDING|EH_EXIT_UNWIND)) && + ret == ExceptionContinueSearch) + { + ERR("noexcept function propagating exception\n"); + terminate(); + } + + return ret; } BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID reserved) -- 2.25.1
Hi Daniel, On 9/30/20 6:49 AM, Daniel Lehman wrote:
+ ret = cxx_frame_handler4(rec, frame, context, dispatch, &descr, trylevel); + if (descr.header & FUNC_DESCR_NO_EXCEPT && + !(rec->ExceptionFlags & (EH_UNWINDING|EH_EXIT_UNWIND)) && + ret == ExceptionContinueSearch) + { + ERR("noexcept function propagating exception\n"); + terminate(); + } This will not work for nested exceptions. You will need to move the handling to cxx_frame_handler4 helper.
Here's an example of non-working code (in noexcept function): try { try { throw 1; } catch (int e) { throw; } } catch (...) { } Thanks, Piotr
participants (2)
-
Daniel Lehman -
Piotr Caban