mingw32 捕获异常的4种方法

-------------------------------------------------------------------------------
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

时间: 2024-10-19 14:09:40

mingw32 捕获异常的4种方法的相关文章

读取Excel文件的两种方法

第一种方法:传统方法,采用OleDB读取EXCEL文件, 优点:写法简单,缺点:服务器必须安有此组件才能用,不推荐使用 private DataSet GetConnect_DataSet2(string fileName) { DataSet myDataSet = new DataSet(); //创建一个数据链接 string strCon = " Provider = Microsoft.Jet.OLEDB.4.0 ; Data Source = " + fileName +

捕获异常的两种方式

捕获异常的两种方式 方法一 #coding=utf-8 import sys try: with open("ddd.txt", "r") as f: data = f.read() print data except: err = sys.exc_info() print err sys.exc_info()返回三元组,分别是,异常类型.异常值.异常追溯地址 方法二 #coding=utf-8 try: with open("ddd.txt",

PDO中执行SQL语句的三种方法

在PDO中,我们可以使用三种方式来执行SQL语句,分别是 exec()方法,query方法,以及预处理语句prepare()和execute()方法~大理石构件来图加工 在上一篇文章<使用PDO构造函数连接数据库及DSN详解>中,我们介绍了如何使用构造函数连接数据库和DSN的详解,那么我们这篇文章跟大家介绍在PDO中执行SQL语句的三种方式,下面我们将一一介绍! 第一种方法:exec()方法 exec()方法返回执行SQL 语句后受影响的行数,其语法格式如下: 1 int PDO::exec(

一、查看Linux内核版本命令(两种方法):

一.查看Linux内核版本命令(两种方法): 1.cat /proc/version [[email protected]CentOS home]# cat /proc/versionLinux version 2.6.32-431.el6.x86_64 ([email protected]) (gcc version 4.4.7 20120313 (Red Hat 4.4.7-4) (GCC) ) #1 SMP Fri Nov 22 03:15:09 UTC 2013 2.uname -a [

利用颜色和形态学两种方法进行车牌区域提取的OpenCV代码

要想提取车牌号,首先你要定位车牌区域嘛,本文分别两种方法用,即颜色和形态学的方法,对车牌区域进行判定.说得是两种方法,其实两种方法并无多大的区别,只是有一步的判断标准不一样而已,你看了下面整理出的的思路就知道两者的区别真的很小了. 方法一:利用颜色提取车牌区域的思路: ①求得原图像的sobel边缘sobelMat ②在HSV空间内利用车牌颜色阈值对图像进行二值化处理,得到图像bw_blue→ ③由下面的判别标准得到图像bw_blue_edge for (int k = 1; k != heigh

ios图片拉伸两种方法

ios图片拉伸两种方法 UIImage *image = [UIImage imageNamed:@"qq"]; 第一种: // 左端盖宽度 NSInteger leftCapWidth = image.size.width * 0.5f; // 顶端盖高度 NSInteger topCapHeight = image.size.height * 0.5f; // 重新赋值 image = [image stretchableImageWithLeftCapWidth:leftCapW

XML解析的几种方法

第一种方法系统自带的解析方法(NSXMLParser) //1.指定XML文件 NSString *path=[[NSBundle mainBundle] pathForResource:@"person" ofType:@"xml"]; //转换成data类型对象 NSData *data=[NSData dataWithContentsOfFile:path]; //2.为parser指定初始值 NSXMLParser *parser=[[NSXMLParser

Spring官网下载dist.zip的几种方法

Spring官网下载dist.zip的几种方法 Spring官网改版后,很多项目的完整zip包下载链接已经隐掉了,虽然Spring旨在引导大家用更“高大上”的maven方式来管理所依赖的jar包,但是完全没想到中国的国情,在伟大的墙内,直接通过maven下载墙外的东西,要么龟速,要么直接被和谐. 下面是从网上搜集的一些方法,可用于一次性下载Spring各项目的完整dist.zip 第一种 直接 http://repo.springsource.org/libs-release-local/org

SSH 框架打开项目自动执行action的第二种方法

web.xml还是什么不配置 <welcome-file-list> <welcome-file></welcome-file> </welcome-file-list> struts.xml加上这个 <default-action-ref name="index" /> 同时原来的修改为这样 <action name="index" class="index"> <r