windows核心编程---异常处理程序与软件异常
来源:互联网 发布:mac散热口在哪 编辑:程序博客网 时间:2024/06/04 23:05
CPU抛出的异常是硬件异常,操作系统和应用程序抛出的异常是软件异常。
硬件或软件异常被抛出时,可用:
__try{}__except(exception filter// 异常过滤程序){// 异常处理程序}
一个__try后,只需跟一个__except或__finally(终止处理程序)。
-异常过滤程序,异常处理程序
异常过滤程序,异常处理程序
主要有系统实现。
只在__try块中发生异常,才会转入__except,__try块未发生异常,不会进入__except块。
异常过滤表达式的值必定为以下三个标识符之一:
EXCEPTION_EXECUTE_HANDLER// 执行__except块中代码
EXCEPTION_CONTINUE_SEARCH// 到上一层__try中寻找异常处理方法
EXCEPTION_CONTINUE_EXECUTION// 忽略异常,继续执行
-EXCEPTION_EXECUTE_HANDLE
执行异常处理块中代码。
执行__except代码块,执行结束,继续往下从__except块后执行。
void FuncOStimpy1(){// 1__try{// 2FuncORen1();}__except(/6/EXCEPTION_EXECUTE_HANDLER){// 8MessageBox(...);}// 9}void FuncORen1(){DWORD dwTemp = 0;// 3__try{// 4WaitForSingleObject(g_hSem, INFINITE);// 5g_dwProtectedData = 5 / dwTemp;}__finally{// 7 // 若在这里直接return,异常处理的8,9不会被执行。相当于本函数正常返回。try/except下多级try/finally类似。ReleaseSemaphore(g_hSem, 1, NULL);}}
-EXCEPTION_CONTINUE_EXECUTION
TCHAR g_szBuffer[100];void FunclinRoosevelt1(){int x = 0;TCHAR *pchBuffer = NULL;__try{*pchBuffer = TEXT('J');x = 5 / x;}__except(/*异常过滤程序,返回值必须为3个异常常量中一个*/OilFilter1(&pchBuffer)){MessageBox(NULL,TEXT("An exception occurred"),NULL,MB_OK);}MessageBox(NULL,TEXT("Function completed"),NULL,MB_OK);}LONG OilFilter1(TCHAR **ppchBuffer){if(*ppchBuffer == NULL){*ppchBuffer = g_szBuffer;// 将控制流跳转到导致异常的那条指令,并尝试重新执行这条指令return EXCEPTION_CONTINUE_EXECUTION;}// 让系统执行except代码块return EXCEPTION_EXECUTE_HANDLER;}
-EXCEPTION_CONTINUE_SEARCH
继续往上层try搜索except.
-GetExceptionCode
__try{x=0;y=4 / x;...}__except(GetExceptionCode() == EXCEPTION_INT_DIVIDE_BY_ZERO)? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH){}// 表明刚刚发生的异常的类型DWORD GetExceptionCode();
// 内存相关异常
EXCEPTION_ACCESS_VIOLATION 写一个错误的虚拟地址
EXCEPTION_DATATYPE_MISALIGNMENT 线程试图从没有提供自动对齐机制的硬件里读入没有对齐的数据。
EXCEPTION_ARRAY_BOUNDS_EXCEEDED 线程在支持边界检查的硬件上访问越界的数组元素。
EXCEPTION_IN_PAGE_ERROR 文件系统或设备取得读取错误而引起的页错误。
EXCEPTION_GUARD_PAGE 线程试图访问具备PAGE_GUARD属性内存页。
EXCEPTION_STACK_OVERFLOW 线程用光栈空间
EXCECPTION_ILLEGAL_INSTRUCTION 非法指令
EXCEPTION_PRIV_INSTRUCTION 试图执行当前机器模式下不允许的操作
// 与异常本身相关的异常
EXCEPTION_INVALID_DISPOSITION 异常过滤返回3个常量以外值
EXCEPTION_NONCONTINUABLE_EXCEPTION 异常过滤返回继续执行,但实际这类异常不能继续
// 与调试相关异常
EXCEPTION_BREAKPOINT 执行到断点
EXCEPTION_SINGLE_STEP 单步
EXCEPTION_INVALID_HANDLE 传入无效句柄给一函数
// 与整型相关的异常
EXCEPTION_INT_DIVIDE_BY_ZERO 线程试图在整数除法运算中以0做除数
EXCEPTION_INT_OVERFLOW 整型运算结果超出范围
// 与浮点类型相关的异常
EXCEPTION_FLT_DENORMAL_OPERAND 浮点运算中一个运算数是不能作为标准浮点数的小数。
EXCEPTION_FLT_DIVIDE_BY_ZERO 线程试图在浮点除法中以0做除数
EXCEPTION_FLT_INEXACT_RESULT 浮点运算结果不能精确地表示为十进制小数
EXCEPTION_FLT_INVALID_OPERATION 其它浮点数异常
EXCEPTION_FLT_OVERFLOW 浮点运算指数部分超出该类型允许的最大值
EXCEPTION_FLT_STACK_CHECK 浮点运算造成栈上溢出或下溢出
EXCEPTION_FLT_UNDERFLOW 浮点运算指数部分小于该类型允许的最小值
GetExceptionCode只能用在异常过滤程序里(仅限与__except后的括号里),或异常处理程序里。
异常代码遵循WinError.h中有关错误代码的规则
-GetExceptionInformation
一个异常发生时,系统将向发生异常的线程的栈中压入3个结构,
// 包含关于抛出异常的信息
EXCEPTION_RECORD,
// 与异常和CPU相关的信息
CONTEXT,
// 含两个指针,指向前两个结构
EXCEPTION_POINTERS。
PEXCEPTION_POINTERS GetExceptionInformation();
这个函数只能在异常过滤程序中调用,因为上述3个结构只在系统计算异常过滤程序时才有效。
仅仅限与_except后的括号里。
typedef struct _EXCEPTION_RECORD{// 异常码DWORD ExceptionCode;// 异常标志DWORD ExceptionFlags;// 异常链struct _EXCEPTION_RECORD *ExceptionRecord;// 导致异常的CPU指令地址PVOID ExceptionAddress;// 异常相关参数个数DWORD NumberParameters;// 描述异常的附加数组ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];}EXCEPTION_RECORD;
对异常EXCEPTION_ACCESS_VIOLATION,
ExceptionInformation[0]:
0,读取不能访问的数据
1,写入不能访问的数据
8,执行不能访问的代码
__try{...}__except(ExpFltr(GetExceptionInformation())){...}LONG ExpFltr(LPEXCEPTION_POINTERS pep){TCHAR szBuf[300], *p;PEXCEPTION_RECORD pER = pep->ExceptionRecord;DWORD dwExceptionCode = pER->ExceptionCode;StringCchPrintf(szBuf,_countof(szBuf),TEXT("Code = %x, Address = %p"),dwExceptionCode,pER->ExceptionAddress);p = _tcschr(szBuf, TEXT('0'));switch(dwExceptionCode){case EXCEPTION_ACCESS_VIOLATION: { StringCchPrintf( p, _countof(szBuf), TEXT("\n--> Attempt to %s data at address %p"), pER->ExceptionInformation[0] ? TEXT("write") : TEXT("read"), pER->ExceptionInformation[1] ); } break;default: break;}MessageBox(NULL,szBuf,TEXT("Exception"),MB_OK | MB_ICONEXCLAMATION);return EXCEPTION_CONTINUE_SEARCH;}
-软件异常
也可在应用代码抛出异常
// 抛出一个软件异常VOID RaiseException(// 要抛出异常标识符。// 如果定义自己的异常标识符,要遵循windows错误代码定义的标准格式。DWORD dwExceptionCode,// 标志:// 0// EXCEPTION_NONCONTINUABLE,此时异常过滤程序不能返回EXCEPTION_CONTINUE_EXECUTION.// 此时,过滤程序若返回EXCEPTION_CONTINUE_EXECUTION,会引发EXCEPTION_NONCONTINUABLE_EXCEPTIONDWORD dwExceptionFlags,// 异常附件信息DWORD nNumberOfArguments,// 异常附件信息CONST ULONG_PTR *pArguments);
- windows核心编程---异常处理程序与软件异常
- 《Windows核心编程》读书笔记二十四章 异常处理程序与软件异常
- 异常处理程序和软件异常——Windows核心编程学习手札之二十四
- Windows核心编程 第2 4章 异常处理程序和软件异常
- (windows编程 学习笔记二) 结构化异常处理(异常处理程序和软件异常)
- windows核心编程---未处理异常,向量化异常处理与C++异常
- Windows核心编程:结构化异常处理
- Windows 核心编程之 异常处理
- WINDOWS核心编程——异常处理
- windows核心编程---结构化异常处理
- Windows核心编程(二十四)终止处理程序及异常处理程序
- windows核心编程--SEH(结构异常处理)
- windows核心编程--SEH(结构异常处理)
- windows核心编程--SEH(结构异常处理)
- windows核心编程--SEH(结构异常处理)
- Java核心编程十:异常处理与日志
- C24、异常处理程序和软件异常
- Windows核心编程笔记(十九) SEH结构化异常处理_未处理异常及向量化异常
- android View的详解 之 自定义view (三)
- 【XSY2524】唯一神 状压DP 矩阵快速幂 FFT
- Sed命令中含有转义字符的解决方法
- Reinforcement Learning:Model-Free Prediction 笔记
- Codeforces Round #453 (Div. 2) A-C
- windows核心编程---异常处理程序与软件异常
- poj2396 Budget
- SDNU 1241
- 北京市交通委:无人驾驶车辆上路测试需配驾驶员
- 激辩AI:有人认为将倒闭一批 有人预判融资额还要涨
- 外媒预测:3D传感智能机将成为2018年大势
- JavaSE--------基础语法(一)
- jQuery事件机制
- 链式编程