Text file src/runtime/testdata/testwinlib/main.c

     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