1 #include <stdio.h>
2 #include <windows.h>
3 #include "testwinlib.h"
4
5 int exceptionCount;
6 int continueCount;
7 int unhandledCount;
8
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 }
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
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
50 void throwFromC()
51 {
52 DebugBreak();
53 }
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
View as plain text