关于捕获硬件异常和软件异常的问题

tlovexyj 2003-05-07 01:37:41
通常soft exception我们用
try
{
}
catch(...)
{
}

hardware exception用
__try
{
}
__exception(...)
{
}


__try
{
}
__finally
{
}


但是他们不能互相包容,也就是指不能这样写:
__try
{
try
{
}
catch(...)
{
}
}
__exception(...)
{
}

但是如果我需要同时捕获一段代码中所有的硬件异常和软件异常,这时怎么办呢?
求大虾指点~

谢谢~~~
...全文
258 6 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
phiger 2003-05-07
  • 打赏
  • 举报
回复
??????????????????
tlovexyj 2003-05-07
  • 打赏
  • 举报
回复
不过我用更简单的方法解决了,以下是源码,散分:

// std35.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream.h>
#include <excpt.h>
#include <eh.h>
#include <windows.h>

void trans_func(unsigned int eCode, _EXCEPTION_POINTERS* pExp)
{
switch (eCode)
{
case EXCEPTION_ACCESS_VIOLATION:
throw exception("The thread tried to read from or write to a virtual address for which it does not have the appropriate access.");

case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
throw exception("The thread tried to access an array element that is out of bounds and the underlying hardware supports bounds checking.");

case EXCEPTION_BREAKPOINT:
throw exception("A breakpoint was encountered.");

case EXCEPTION_DATATYPE_MISALIGNMENT:
throw exception("The thread tried to read or write data that is misaligned on hardware that does not provide alignment. For example, 16-bit values must be aligned on 2-byte boundaries; 32-bit values on 4-byte boundaries, and so on.");

case EXCEPTION_FLT_DENORMAL_OPERAND:
throw exception("One of the operands in a floating-point operation is denormal. A denormal value is one that is too small to represent as a standard floating-point value.");

case EXCEPTION_FLT_DIVIDE_BY_ZERO:
throw exception("The thread tried to divide a floating-point value by a floating-point divisor of zero.");

case EXCEPTION_FLT_INEXACT_RESULT:
throw exception("The result of a floating-point operation cannot be represented exactly as a decimal fraction.");

case EXCEPTION_FLT_INVALID_OPERATION:
throw exception("This exception represents any floating-point exception not included in this list.");

case EXCEPTION_FLT_OVERFLOW:
throw exception("The exponent of a floating-point operation is greater than the magnitude allowed by the corresponding type.");

case EXCEPTION_FLT_STACK_CHECK:
throw exception("The stack overflowed or underflowed as the result of a floating-point operation.");

case EXCEPTION_FLT_UNDERFLOW:
throw exception("The exponent of a floating-point operation is less than the magnitude allowed by the corresponding type.");

case EXCEPTION_ILLEGAL_INSTRUCTION:
throw exception("The thread tried to execute an invalid instruction.");

case EXCEPTION_IN_PAGE_ERROR:
throw exception("The thread tried to access a page that was not present, and the system was unable to load the page. For example, this exception might occur if a network connection is lost while running a program over the network.");

case EXCEPTION_INT_DIVIDE_BY_ZERO:
throw exception("The thread tried to divide an integer value by an integer divisor of zero.");

case EXCEPTION_INT_OVERFLOW:
throw exception("The result of an integer operation caused a carry out of the most significant bit of the result.");

case EXCEPTION_INVALID_DISPOSITION:
throw exception("An exception handler returned an invalid disposition to the exception dispatcher. Programmers using a high-level language such as C should never encounter this exception.");

case EXCEPTION_NONCONTINUABLE_EXCEPTION:
throw exception("The thread tried to continue execution after a noncontinuable exception occurred.");

case EXCEPTION_PRIV_INSTRUCTION:
throw exception("The thread tried to execute an instruction whose operation is not allowed in the current machine mode.");

case EXCEPTION_SINGLE_STEP:
throw exception("A trace trap or other single-instruction mechanism signaled that one instruction has been executed.");

case EXCEPTION_STACK_OVERFLOW:
throw exception("The thread used up its stack.");

default:
throw exception("Unknow exception!");
}
}

#include <vector>

void Run()
{
int sz[2];
int *p1 = 0x00000000;
int *p2;

std::vector<int> vec(4);

throw exception("nothing");

int a=5, b=0;
a = a / b;
*p1 = 1;
a = vec[1000];
*p2 = 2;
}

void Func()
{
__try
{
Run();
}
__finally
{
cout << "finally" << endl;
}
}

int main(int argc, char* argv[])
{
_set_se_translator( trans_func );
try
{
Func();
}
catch(exception &e)
{
cout << e.what() << endl;
}

cout << "game over" << endl;

return 0;
}
tlovexyj 2003-05-07
  • 打赏
  • 举报
回复
谢谢,我已经解决:

Exception Handling Differences
Home | Overview | How Do I | FAQ

The major difference between structured exception handling and C++ exception handling is that the C++ exception handling model deals in types, while the C structured exception handling model deals with exceptions of one type — specifically, unsigned int. That is, C exceptions are identified by an unsigned integer value, whereas C++ exceptions are identified by data type. When an exception is raised in C, each possible handler executes a filter that examines the C exception context and determines whether to accept the exception, pass it to some other handler, or ignore it. When an exception is thrown in C++, it may be of any type.

A second difference is that the C structured exception handling model is referred to as “asynchronous” in that exceptions occur secondary to the normal flow of control. The C++ exception handling mechanism is fully “synchronous,” which means that exceptions occur only when they are thrown.

If a C exception is raised in a C++ program, it can be handled by a structured exception handler with its associated filter or by a C++ catch handler, whichever is dynamically nearer to the exception context. For example, the following C++ program raises a C exception inside a C++ try context:

#include <iostream.h>

void SEHFunc( void );

int main()
{
try
{
SEHFunc();
}
catch( ... )
{
cout << "Caught a C exception."<< endl;
}
return 0;
}
void SEHFunc()
{
__try
{
int x, y = 0;
x = 5 / y;
}
__finally
{
cout << "In finally." << endl;
}
}

This is the output from the preceding example:

In finally.
Caught a C exception.

C Exception Wrapper Class
In a simple example like the above, the C exception can be caught only by an ellipsis (...) catch handler. No information about the type or nature of the exception is communicated to the handler. While this method works, in some cases you may need to define a transformation between the two exception handling models so that each C exception is associated with a specific class. To do this, you can define a C exception "wrapper" class, which can be used or derived from in order to attribute a specific class type to a C exception. By doing so, each C exception can be handled by a C++ catch handler more separately than in the preceding example.

Your wrapper class might have an interface consisting of some member functions that determine the value of the exception, and that access the extended exception context information provided by the C exception model. You might also want to define a default constructor and a constructor that accepts an unsigned int argument (to provide for the underlying C exception representation), and a bitwise copy constructor. The following is a possible implementation of a C exception wrapper class:

class SE_Exception
{
private:
SE_Exception() {}
SE_Exception( SE_Exception& ) {}
unsigned int nSE;
public:
SE_Exception( unsigned int n ) : nSE( n ) {}
~SE_Exception() {}
unsigned int getSeNumber() { return nSE; }
};

To use this class, you install a custom C exception translation function that is called by the internal exception handling mechanism each time a C exception is thrown. Within your translation function, you can throw any typed exception (perhaps an SE_Exception type, or a class type derived from SE_Exception) that can be caught by an appropriate matching C++ catch handler. The translation function can simply return, which indicates that it did not handle the exception. If the translation function itself raises a C exception, terminate is called.

To specify a custom translation function, call the _set_se_translator function with the name of your translation function as its single argument. The translation function that you write is called once for each function invocation on the stack that has try blocks. There is no default translation function; if you do not specify one by calling _set_se_translator, the C exception can only be caught by an ellipsis catch handler.

For example, the following code installs a custom translation function, then raises a C exception that is wrapped by the SE_Exception class:

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

class SE_Exception {
private:
SE_Exception() {}
SE_Exception( SE_Exception& ) {}
unsigned int nSE;
public:
SE_Exception(unsigned int n) : nSE(n) {}
~SE_Exception() {}
unsigned int getSeNumber() { return nSE; }
};

void SEFunc(void);
void trans_func( unsigned, _EXCEPTION_POINTERS*);

int main()
{
_set_se_translator( trans_func );
try
{
SEFunc();
}
catch( SE_Exception e )
{
printf( "Caught a __try exception with SE_Exception.\n" );
printf( "nSE = 0x%x\n", e.getSeNumber() );
}
return 0;
}
void SEFunc()
{
__try
{
int x, y=0;
x = 5 / y;
}
__finally
{
printf( "In finally\n" );
}
}
void trans_func( unsigned int u, _EXCEPTION_POINTERS* pExp )
{
printf( "In trans_func.\n" );
throw SE_Exception( u );

功名半纸 2003-05-07
  • 打赏
  • 举报
回复
同意 phiger(phiger)
phiger 2003-05-07
  • 打赏
  • 举报
回复
You cannot use both __try/__except (structured exception handling) and try/catch (C++ exception handling) in the same function

but you can like that:
#include <stdio.h>
void test();
int main(int argc, char* argv[])
{
puts("hello");
try
{
test();
puts("in try");
}
catch(...)
{
puts("in catch");
}
puts("world");
return 0;
}
void test()
{
int* p = 0x00000000; // pointer to NULL

__try{
puts("in __try");
*p = 13; // causes an access violation exception;
}
__except(puts("in __except"), 1)
{
puts("in __except");
}
}
dizzo 2003-05-07
  • 打赏
  • 举报
回复
gz

16,548

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • AIGC Browser
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧