From 57d6883868529f793012a4762b7a8cd038b3af9d Mon Sep 17 00:00:00 2001 From: Daniel Lehman Date: Fri, 21 Apr 2017 12:41:31 -0700 Subject: [PATCH] msvcrt: Stop at trylevel for ControlPc on target frame for non-consolidate unwinds // results are same with either /EHa or /EHs // cl.exe /Od /MD /EHa /nologo standalone.cpp /* on Windows: klass::klass: 7: jmp_target:29 id = 1 klass::klass: 7: jmp_target:35 id = 2 klass::klass: 7: jmp_inner:22 id = 3 klass::~klass: 9: jmp_inner:22 id = 3 klass::klass: 7: jmp_target:32 id = 4 klass::~klass: 9: jmp_target:32 id = 4 klass::~klass: 9: jmp_target:29 id = 1 on Wine (without attached 0002): klass::klass: 7: jmp_target:29 id = 1 klass::klass: 7: jmp_target:35 id = 2 klass::klass: 7: jmp_inner:22 id = 3 klass::~klass: 9: jmp_inner:22 id = 3 klass::~klass: 9: jmp_target:35 id = 2 <- destructor for k2 before jmp_inner not called on Windows klass::~klass: 9: jmp_target:29 id = 1 <- destructor for k called prematurely klass::klass: 7: jmp_target:32 id = 4 klass::~klass: 9: jmp_target:32 id = 4 klass::~klass: 9: jmp_target:29 id = 1 <- destructor for k called above --^ */ struct klass { klass(const char *a, int l) : msg(a), lineno(l), myid(++id) {printf("%s: %i: %s:%i id = %i\n", __FUNCTION__, __LINE__, msg, lineno, myid); fflush(stdout);} ~klass(void) {printf("%s: %i: %s:%i id = %i\n", __FUNCTION__, __LINE__, msg, lineno, myid); fflush(stdout);} const char *msg; int lineno; int myid; static int id; }; int klass::id = 0; jmp_buf buf; void jmp_inner(void) // this whole frame should unwind to -1 { klass k(__FUNCTION__, __LINE__); longjmp(buf, 1); printf("%s: %i: SHOULD NOT BE PRINTED\n", __FUNCTION__, __LINE__); } void jmp_target(void) // this target frame should unwind to trylevel == 1 { klass k(__FUNCTION__, __LINE__); if (_setjmp(buf)) { klass k(__FUNCTION__, __LINE__); return; } klass k2(__FUNCTION__, __LINE__); jmp_inner(); printf("%s: %i: SHOULD NOT BE PRINTED\n", __FUNCTION__, __LINE__); } int main(int argc, char **argv) { jmp_target(); return 0; } Signed-off-by: Daniel Lehman --- dlls/msvcrt/except_x86_64.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dlls/msvcrt/except_x86_64.c b/dlls/msvcrt/except_x86_64.c index 8210f7b..e891567 100644 --- a/dlls/msvcrt/except_x86_64.c +++ b/dlls/msvcrt/except_x86_64.c @@ -515,7 +515,7 @@ static DWORD cxx_frame_handler(EXCEPTION_RECORD *rec, ULONG64 frame, } if (frame == orig_frame) - cxx_local_unwind(frame, dispatch, descr, -1); + cxx_local_unwind(frame, dispatch, descr, rec->ExceptionFlags & EH_TARGET_UNWIND ? trylevel : -1); return ExceptionContinueSearch; } if (!descr->tryblock_count) return ExceptionContinueSearch; -- 1.9.5