1 #include <stdio.h>
2 #include <windows.h>
3 #include "testwinlib.h"
4 
5 int exceptionCount;
6 int continueCount;
7 int unhandledCount;
8 
customExceptionHandlder(struct _EXCEPTION_POINTERS * ExceptionInfo)9 LONG WINAPI customExceptionHandlder(struct _EXCEPTION_POINTERS *ExceptionInfo)
10 {
11     if (ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_BREAKPOINT)
12     {
13         exceptionCount++;
14         // prepare context to resume execution
15         CONTEXT *c = ExceptionInfo->ContextRecord;
16 #ifdef _AMD64_
17         c->Rip = *(DWORD64 *)c->Rsp;
18         c->Rsp += 8;
19 #elif defined(_X86_)
20         c->Eip = *(DWORD *)c->Esp;
21         c->Esp += 4;
22 #else
23         c->Pc = c->Lr;
24 #endif
25 #ifdef _ARM64_
26         // TODO: remove when windows/arm64 supports SEH stack unwinding.
27         return EXCEPTION_CONTINUE_EXECUTION;
28 #endif
29     }
30     return EXCEPTION_CONTINUE_SEARCH;
31 }
customContinueHandlder(struct _EXCEPTION_POINTERS * ExceptionInfo)32 LONG WINAPI customContinueHandlder(struct _EXCEPTION_POINTERS *ExceptionInfo)
33 {
34     if (ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_BREAKPOINT)
35     {
36         continueCount++;
37     }
38     return EXCEPTION_CONTINUE_SEARCH;
39 }
40 
unhandledExceptionHandler(struct _EXCEPTION_POINTERS * ExceptionInfo)41 LONG WINAPI unhandledExceptionHandler(struct _EXCEPTION_POINTERS *ExceptionInfo) {
42     if (ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_BREAKPOINT)
43     {
44         unhandledCount++;
45         return EXCEPTION_CONTINUE_EXECUTION;
46     }
47     return EXCEPTION_CONTINUE_SEARCH;
48 }
49 
throwFromC()50 void throwFromC()
51 {
52     DebugBreak();
53 }
main()54 int main()
55 {
56     // simulate a "lazily" attached debugger, by calling some go code before attaching the exception/continue handler
57     Dummy();
58     exceptionCount = 0;
59     continueCount = 0;
60     void *exceptionHandlerHandle = AddVectoredExceptionHandler(0, customExceptionHandlder);
61     if (NULL == exceptionHandlerHandle)
62     {
63         printf("cannot add vectored exception handler\n");
64         fflush(stdout);
65         return 2;
66     }
67     void *continueHandlerHandle = AddVectoredContinueHandler(0, customContinueHandlder);
68     if (NULL == continueHandlerHandle)
69     {
70         printf("cannot add vectored continue handler\n");
71         fflush(stdout);
72         return 2;
73     }
74     void *prevUnhandledHandler = SetUnhandledExceptionFilter(unhandledExceptionHandler);
75     CallMeBack(throwFromC);
76     RemoveVectoredContinueHandler(continueHandlerHandle);
77     RemoveVectoredExceptionHandler(exceptionHandlerHandle);
78     if (prevUnhandledHandler != NULL)
79     {
80         SetUnhandledExceptionFilter(prevUnhandledHandler);
81     }
82     printf("exceptionCount: %d\ncontinueCount: %d\nunhandledCount: %d\n", exceptionCount, continueCount, unhandledCount);
83     fflush(stdout);
84     return 0;
85 }
86