From bc15070085ec417d4254f8a4eda62b42de88fb37 Mon Sep 17 00:00:00 2001 From: qmuntal Date: Mon, 4 Sep 2023 17:30:08 +0200 Subject: runtime: support SetUnhandledExceptionFilter on Windows The Windows unhandled exception mechanism fails to call the callback set in SetUnhandledExceptionFilter if the stack can't be correctly unwound. Some cgo glue code was not properly chaining the frame pointer, making the stack unwind to fail in case of an exception inside a cgo call. This CL fix that and adds a test case to avoid regressions. Fixes #50951 Change-Id: Ic782b5257fe90b05e3def8dbf0bb8d4ed37a190b Reviewed-on: https://go-review.googlesource.com/c/go/+/525475 Reviewed-by: Bryan Mills Reviewed-by: Cherry Mui Run-TryBot: Quim Muntal LUCI-TryBot-Result: Go LUCI TryBot-Result: Gopher Robot --- src/runtime/testdata/testwinlib/main.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) (limited to 'src/runtime/testdata/testwinlib') diff --git a/src/runtime/testdata/testwinlib/main.c b/src/runtime/testdata/testwinlib/main.c index 55ee6571d7..e9b5946a31 100644 --- a/src/runtime/testdata/testwinlib/main.c +++ b/src/runtime/testdata/testwinlib/main.c @@ -4,6 +4,8 @@ int exceptionCount; int continueCount; +int unhandledCount; + LONG WINAPI customExceptionHandlder(struct _EXCEPTION_POINTERS *ExceptionInfo) { if (ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_BREAKPOINT) @@ -20,7 +22,10 @@ LONG WINAPI customExceptionHandlder(struct _EXCEPTION_POINTERS *ExceptionInfo) #else c->Pc = c->Lr; #endif +#ifdef _ARM64_ + // TODO: remove when windows/arm64 supports SEH stack unwinding. return EXCEPTION_CONTINUE_EXECUTION; +#endif } return EXCEPTION_CONTINUE_SEARCH; } @@ -29,6 +34,14 @@ LONG WINAPI customContinueHandlder(struct _EXCEPTION_POINTERS *ExceptionInfo) if (ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_BREAKPOINT) { continueCount++; + } + return EXCEPTION_CONTINUE_SEARCH; +} + +LONG WINAPI unhandledExceptionHandler(struct _EXCEPTION_POINTERS *ExceptionInfo) { + if (ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_BREAKPOINT) + { + unhandledCount++; return EXCEPTION_CONTINUE_EXECUTION; } return EXCEPTION_CONTINUE_SEARCH; @@ -58,10 +71,15 @@ int main() fflush(stdout); return 2; } + void *prevUnhandledHandler = SetUnhandledExceptionFilter(unhandledExceptionHandler); CallMeBack(throwFromC); RemoveVectoredContinueHandler(continueHandlerHandle); RemoveVectoredExceptionHandler(exceptionHandlerHandle); - printf("exceptionCount: %d\ncontinueCount: %d\n", exceptionCount, continueCount); + if (prevUnhandledHandler != NULL) + { + SetUnhandledExceptionFilter(prevUnhandledHandler); + } + printf("exceptionCount: %d\ncontinueCount: %d\nunhandledCount: %d\n", exceptionCount, continueCount, unhandledCount); fflush(stdout); return 0; } -- cgit v1.3