mingw32 捕获异常的4种方法

本文详细介绍了在mingw32环境下,使用C/C++编程时捕获异常的四种有效方法,包括标准异常处理、SEH、longjmp以及自定义异常框架的应用,帮助开发者更好地理解和应对程序运行中的异常状况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

-------------------------------------------------------------------------------
1. 利用 windows 的API SetUnhandledExceptionFilter
-------------------------------------------------------------------------------
#include <windows.h>
#include <stdio.h>

LONG WINAPI UnhandledExceptionFilter2(LPEXCEPTION_POINTERS pep)
{
  int code =  pep->ExceptionRecord->ExceptionCode;
  int flags = pep->ExceptionRecord->ExceptionFlags;
  printf("Exception Caught: Code = %i, Flags = %i, Desc = %s\n", code,
     flags, GetExceptionDescription(code));
  if (flags == EXCEPTION_NONCONTINUABLE)
  {
  MessageBox(NULL, "Cannot continue; that would only generate another exception!",
       "Exception Caught", MB_OK);
  return EXCEPTION_EXECUTE_HANDLER;
  }
  pep->ContextRecord->Eip -= 8;
  return EXCEPTION_CONTINUE_EXECUTION;
}

int testxcpt()
{
  LPTOP_LEVEL_EXCEPTION_FILTER pOldFilter;
  char *s = NULL;
  int rc = FALSE;

  pOldFilter = SetUnhandledExceptionFilter(UnhandledExceptionFilter2);
  printf("Generate exception? y/n: ");
  fflush(stdin);
  switch(getchar())
  {
  case 'y':
  case 'Y':
  *s = *s;
  break;
  case 'n':
  case 'N':
  s = "s";
  rc = TRUE;
  break;
  default:
  printf("I said enter y or n!\n");
  }
  SetUnhandledExceptionFilter(pOldFilter);

  return rc;
}

int main()
{
  if (testxcpt())
  printf("testxcpt() succeeded\n");
  else
  printf("testxcpt() failed\n");
  return 0;
}
-------------------------------------------------------------------------------
2. "excpt.h" - __try1
-------------------------------------------------------------------------------
#include <windows.h>
#include <stdio.h>
#include <excpt.h>

char *GetExceptionDescription(LONG code);

EXCEPTION_DISPOSITION MyHandler (struct _EXCEPTION_RECORD* er, void* buf, struct _CONTEXT* ctx, void* buf2)
{
  printf("ExceptionCode  = %08X %s\n"
    "ExceptionFlags = %08X\n"
     "ContextFlags   = %08X\n"
     "SegGs  = %08X\n"
     "SegFs  = %08X\n"
     "SegEs  = %08X\n"
     "SegDs  = %08X\n"
     "Edi  = %08X\n"
     "Esi  = %08X\n"
     "Ebx  = %08X\n"
     "Edx  = %08X\n"
     "Ecx  = %08X\n"
     "Eax  = %08X\n"
     "Ebp  = %08X\n"
     "Eip  = %08X\n"
     "SegCs  = %08X\n"
     "EFlags = %08X\n"
     "Esp  = %08X\n"
     "SegSs  = %08X\n",
     er->ExceptionCode,
     GetExceptionDescription(er->ExceptionCode),
     er->ExceptionFlags,
     ctx->ContextFlags,
     ctx->SegGs,
     ctx->SegFs,
     ctx->SegEs,
     ctx->SegDs,
     ctx->Edi,
     ctx->Esi,
     ctx->Ebx,
     ctx->Edx,
     ctx->Ecx,
     ctx->Eax,
     ctx->Ebp,
     ctx->Eip,
     ctx->SegCs,
     ctx->EFlags,
     ctx->Esp,
     ctx->SegSs
    );
  return ExceptionNestedException;
}

int main(void)
{
  __try1(MyHandler)
  {
  int *p=(int*)0x00001234;
  *p=12;
  }
  __except1;
  {
  printf("Exception Caught");
  }
  return 0;
}
-------------------------------------------------------------------------------
3. libseh
-------------------------------------------------------------------------------
LibSEH is a compatibility layer that allows one to utilize the Structured Exception Handling facility found in Windows within GNU C/C++ for Windows (MINGW32, CYGWIN). In other compilers, SEH is built into the compiler as a language extension. In other words, this syntax is not standard C or C++, where standard in this case includes any ANSI standard. Usually, support for this feature is implemented through __try, __except, and __finally compound statements.

在 mingw32 中使用最好

GetExceptionCode()  fix to -> GetExceptionCodeSEH()
GetExceptionInformation() fix to -> GetExceptionInformationSEH()

#include <windows.h>
#include <stdio.h>

/* The LibSEH header needs to be included */
#include <seh.h>
char *GetExceptionDescription(LONG code);

int ExceptionFilter(unsigned int code, unsigned int excToFilter)
{
  printf("ExceptionCode = %08X %s\n", code, GetExceptionDescription(code) );
  if(code == excToFilter) return EXCEPTION_EXECUTE_HANDLER;
  else      return EXCEPTION_CONTINUE_SEARCH;
}

int main()
{
  __seh_try
  {
  int x = 0;
  int y = 4;
  y /= x;
  }
  __seh_except(ExceptionFilter(GetExceptionCodeSEH(), EXCEPTION_INT_DIVIDE_BY_ZERO))
  {
  printf("Divide by zero exception.\n");
  }
  __seh_end_except

  __seh_try
  {
  int *p=(int*)0x00001234;
  *p=12;
  }
  __seh_except(ExceptionFilter(GetExceptionCodeSEH(), EXCEPTION_ACCESS_VIOLATION))
  {
  printf("Exception Caught.\n");
  }
  __seh_end_except
  
  return 0;
}

Note:
  http://www.programmingunlimited.net/siteexec/content.cgi?page=libseh
  http://www.programmingunlimited.net/files/libseh-0.0.4.zip
-------------------------------------------------------------------------------
4. exceptions4c
-------------------------------------------------------------------------------
exceptions4c is a tiny, portable framework that brings the power of exceptions to your C applications. It provides a simple set of keywords (macros, actually) which map the semantics of exception handling you're probably already used to: try, catch, finally, throw. You can write try/catch/finally blocks just as if you were coding in Java. This way you will never have to deal again with boring error codes, or check return values every time you call a function.

If you are using threads in your program, you must enable the thread-safe version of the library by defining E4C_THREADSAFE at compiler level.

The usage of the framework does not vary between single and multithreaded programs. The same semantics apply. The only caveat is that the behavior of signal handling is undefined in a multithreaded program so use this feature with caution.

在 mingw32 中, 编译时需要加 -DE4C_THREADSAFE 参数

#include <e4c.h>
#include <stdio.h>

int main(void)
{
  printf("enter main()\n");
  int * pointer = NULL;
  int i=0;
  e4c_context_begin(E4C_TRUE);
  try
  {
  printf("enter try\n");
  int oops = *pointer;
  }
  catch(RuntimeException)
  {
  const e4c_exception * exception = e4c_get_exception();
  printf("Exception Caught.\n");
  if(exception)
  {
    printf( "  exception->name       %s\n"
      "  exception->message    %s\n"
      "  exception->file       %s\n"
      "  exception->line       %ld\n"
      "  exception->function     %s\n",
      exception->name,
      exception->message,
      exception->file,
      exception->line,
      exception->function );
  }
  }
  finally
  {
  printf("finally.\n");
  }
  e4c_context_end();
  return 0;
}

Note:
  https://github.com/guillermocalvo/exceptions4c
  https://github.com/guillermocalvo/exceptions4c/archive/master.zip   <- 3.0.6
  https://github.com/guillermocalvo/exceptions4c/archive/v3.0.5.tar.gz
libseh-0.0.4__exceptions4c-3.0.6.7z

转载于:https://www.cnblogs.com/nlsoft/p/5794108.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值