c++ 标准异常:
/**************************************************************************
*
* stdexcept.cpp - Illustrate the use of C++ Standard Library exceptions.
*
* $Id: stdexcept.cpp 550991 2007-06-26 23:58:07Z sebor $
*
***************************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
* implied. See the License for the specific language governing
* permissions and limitations under the License.
*
* Copyright 1994-2005 Rogue Wave Software.
*
**************************************************************************/
#include <string> // for string
#include <stdexcept> // for exception, runtime_error, out_of_range
#include <iostream> // for cout
#include <conio.h>
//stdexcept.cpp c++标准异常类
#ifndef _RWSTD_NO_EXCEPTIONS
int main () {
// First we'll incite and catch an exception from the C++ Standard
// library class std::string by attempting to replace a substring
// starting at a position beyond the end of the string object.
try {
std::string ().replace (100, 1, 1, 'c');
}catch(int id)
{
std::cout<<id<<std::endl;
}
catch (std::out_of_range &e) {
// Print out the exception string, which in this implementation
// includes the location and the name of the function that threw
// the exception along with the reason for the exception.
std::cout << "Caught an out_of_range exception: "
<< e.what () << '\n';
}
catch (std::exception &e) {
std::cout << "Caught an exception of an unexpected type: "
<< e.what () << '\n';
}
catch (...) {
std::cout << "Caught an unknown exception\n";
}
// Throw another exception.
try {
throw std::runtime_error ("a runtime error");
}
catch (std::runtime_error &e) {
std::cout << "Caught a runtime_error exception: "
<< e.what () << '\n';
}
catch (std::exception &e) {
std::cout << "Caught an exception of an unexpected type: "
<< e.what () << '\n';
}
catch (...) {
std::cout << "Caught an unknown exception\n";
}
getch();
return 0;
}
#else // if defined (_RWSTD_NO_EXCEPTIONS)
int main () {
std::cout << "Exception support disabled.\n";
getch();
return 0;
}
#endif // _RWSTD_NO_EXCEPTIONS
VC MSDN上官方的__except例子
// exceptions_try_except_Statement.cpp
// Example of try-except and try-finally statements
#include <stdio.h>
#include <windows.h> // for EXCEPTION_ACCESS_VIOLATION
#include <excpt.h>
#include <conio.h>
//VC MSDN上官方的__except例子
int filter(unsigned int code, struct _EXCEPTION_POINTERS *ep) {
puts("in filter.");
if (code == EXCEPTION_ACCESS_VIOLATION) {
puts("caught AV as expected.");
return EXCEPTION_EXECUTE_HANDLER;
}
else {
puts("didn't catch AV, unexpected.");
return EXCEPTION_CONTINUE_SEARCH;
};
}
int main()
{
int* p = 0x00000000; // pointer to NULL
puts("hello");
__try{
puts("in try");
__try{
puts("in try");
*p = 13; // causes an access violation exception;
}__finally{
puts("in finally. termination: ");
puts(AbnormalTermination() ? "\tabnormal" : "\tnormal");
}
}__except(filter(GetExceptionCode(), GetExceptionInformation())){
puts("in except");
}
puts("world");
getch();
}
VC SEH
#include <stdio.h>
#include <Windows.h>
#include <exception>
#include <conio.h>
#define CPPEX TRUE
class TestClass
{
public:
~TestClass()
{
printf("Destroying TestClass!\r\n");
}
};
__declspec(noinline) void TestCPPEX()
{
#ifdef CPPEX
printf("Throwing C++ exception\r\n");
throw std::exception("");
#else
printf("Triggering SEH exception\r\n");
volatile int *pInt = 0x00000000;
*pInt = 20;
#endif
}
__declspec(noinline) void TestExceptions()
{
TestClass d;
TestCPPEX();
}
//http://msdn.microsoft.com/en-us/library/swezty51.aspx /EHsc /EHa
int main()
{
__try
{
TestExceptions();
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
printf("Executing SEH __except block\r\n");
}
getch();
return 0;
}
#include <conio.h>
#include <stdio.h>
#include <Windows.h>
#include <tchar.h>
#include <strsafe.h>
void testTerminationHandler()
{
LPTSTR lpBuffer = NULL;
CRITICAL_SECTION CriticalSection;
InitializeCriticalSection(&CriticalSection);
// EnterCriticalSection synchronizes code with other threads.
EnterCriticalSection(&CriticalSection);
__try{
__try
{
printf("9 ");
// Perform a task that may cause an exception.
lpBuffer = (LPTSTR) LocalAlloc(LPTR, 10);
StringCchCopy(lpBuffer, 10, TEXT("Hello"));
_tprintf(TEXT("%s\n"),lpBuffer);
LocalFree(lpBuffer);
printf("11 ");
}__finally
{
printf("10 ");
// LeaveCriticalSection is called even if an exception occurred.
LeaveCriticalSection(&CriticalSection);
}
}__except(1){
printf("12 ");
}
//DeleteCriticalSection(&CriticalSection);
}
//http://msdn.microsoft.com/en-us/library/windows/desktop/ms681409(v=vs.85).aspx
BOOL SafeDiv(INT32 dividend, INT32 divisor, INT32 *pResult)
{
__try
{
printf("6 ");
*pResult = dividend / divisor;
printf("8 ");
}
__except(GetExceptionCode() == EXCEPTION_INT_DIVIDE_BY_ZERO ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
{
printf("7 ");
return FALSE;
}
return TRUE;
}
BOOL CheckForDebugger()
{
__try
{
printf("4 ");
DebugBreak();//触发断点
}
__except(GetExceptionCode() == EXCEPTION_BREAKPOINT ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
{
// No debugger is attached, so return FALSE
// and continue.
printf("5 ");
return FALSE;
}
return TRUE;
}
DWORD FilterFunction()
{
printf("1 "); // printed first
return EXCEPTION_EXECUTE_HANDLER;
}
VOID main(VOID)
{
__try
{
__try
{
RaiseException(
1, // exception code
0, // continuable exception
0, NULL); // no arguments
}
__finally
{
printf("2 "); // this is printed second
}
}
__except ( FilterFunction() )
{
printf("3\n"); // this is printed last
}
CheckForDebugger();
INT32 n;
SafeDiv(100,0,&n);
testTerminationHandler();
getch();// 1 2 3
}
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <conio.h>
// NOTE: The CONTEXT structure contains processor-specific
// information. This sample was designed for X86 processors.
//addVectoredExceptionHandler constants:
//CALL_FIRST means call this exception handler first;
//CALL_LAST means call this exception handler last
#define CALL_FIRST 1
#define CALL_LAST 0
LONG Sequence=1;
LONG Actual[3];
LONG WINAPI VectoredHandler1(
struct _EXCEPTION_POINTERS *ExceptionInfo
)
{
UNREFERENCED_PARAMETER(ExceptionInfo);
Actual[0] = Sequence++;
return EXCEPTION_CONTINUE_SEARCH;
}
LONG WINAPI VectoredHandler2(
struct _EXCEPTION_POINTERS *ExceptionInfo
)
{
UNREFERENCED_PARAMETER(ExceptionInfo);
Actual[1] = Sequence++;
return EXCEPTION_CONTINUE_SEARCH;
}
LONG WINAPI VectoredHandler3(
struct _EXCEPTION_POINTERS *ExceptionInfo
)
{
UNREFERENCED_PARAMETER(ExceptionInfo);
Actual[2] = Sequence++;
return EXCEPTION_CONTINUE_SEARCH;
}
LONG WINAPI VectoredHandlerSkip1(
struct _EXCEPTION_POINTERS *ExceptionInfo
)
{
PCONTEXT Context;
Sequence++;
Context = ExceptionInfo->ContextRecord;
Actual[0] = 0xcc;
#ifdef _AMD64_
Context->Rip++;
#else
Context->Eip++;
#endif
return EXCEPTION_CONTINUE_EXECUTION;
}
LONG WINAPI VectoredHandlerSkip2(
struct _EXCEPTION_POINTERS *ExceptionInfo
)
{
PCONTEXT Context;
Sequence++;
Context = ExceptionInfo->ContextRecord;
Actual[1] = 0xcc;
#ifdef _AMD64_
Context->Rip++;
#else
Context->Eip++;
#endif
return EXCEPTION_CONTINUE_EXECUTION;
}
LONG WINAPI VectoredHandlerSkip3(
struct _EXCEPTION_POINTERS *ExceptionInfo
)
{
PCONTEXT Context;
Sequence++;
Context = ExceptionInfo->ContextRecord;
Actual[2] = 0xcc;
#ifdef _AMD64_
Context->Rip++;
#else
Context->Eip++;
#endif
return EXCEPTION_CONTINUE_EXECUTION;
}
BOOL CheckTest(
char *Variation,
PLONG e,
PLONG a
)
{
int i;
BOOL Pass = TRUE;
for(i=0;i<3;i++)
{
if (e[i] != a[i])
{
if (Variation)
{
printf("%s Failed at %d Expected %d vs Actual %d\n",
Variation, i, e[i], a[i]);
}
Pass = FALSE;
}
// Clear actual for next pass.
a[i] = 0;
}
// Get ready for next pass.
Sequence = 1;
if (Variation)
{
printf("Variation %s %s\n", Variation,
Pass ? "Passed" : "Failed");
}
return Pass;
}
void CheckAllClear()
{
LONG e[3];
BOOL b = 0;
e[0]=0;e[1]=0;e[2]=0;
__try
{
RaiseException(1,0,0,NULL);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
b = CheckTest(NULL,e,Actual);
}
if (!b)
{
printf("Fatal error, handlers still registered.\n");
}
}
void IllegalInst()
{
char *ptr = 0;
*ptr = 0;
}
void Test1()
{
PVOID h1,h2,h3;
LONG e[3];
e[0]=1;e[1]=2;e[2]=3;
h2 = AddVectoredExceptionHandler(CALL_FIRST,VectoredHandler2);
h3 = AddVectoredExceptionHandler(CALL_LAST,VectoredHandler3);
h1 = AddVectoredExceptionHandler(CALL_FIRST,VectoredHandler1);
__try
{
RaiseException(1,0,0,NULL);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
CheckTest("Test1a",e,Actual);
}
RemoveVectoredExceptionHandler(h1);
RemoveVectoredExceptionHandler(h3);
RemoveVectoredExceptionHandler(h2);
CheckAllClear();
}
void Test2()
{
PVOID h1,h2,h3;
LONG e[3];
e[0]=0xcc;e[1]=0;e[2]=0;
h1 = AddVectoredExceptionHandler(1,VectoredHandlerSkip1);
IllegalInst();
CheckTest("Test2a",e,Actual);
RemoveVectoredExceptionHandler(h1);
CheckAllClear();
e[0]=1;e[1]=2;e[2]=0xcc;
h2 = AddVectoredExceptionHandler(CALL_FIRST,VectoredHandler2);
h3 = AddVectoredExceptionHandler(CALL_LAST,VectoredHandlerSkip3);
h1 = AddVectoredExceptionHandler(CALL_FIRST,VectoredHandler1);
IllegalInst();
CheckTest("Test2b",e,Actual);
RemoveVectoredExceptionHandler(h1);
RemoveVectoredExceptionHandler(h2);
RemoveVectoredExceptionHandler(h3);
CheckAllClear();
e[0]=1;e[1]=0xcc;e[2]=0;
h1 = AddVectoredExceptionHandler(CALL_LAST,VectoredHandler1);
h2 = AddVectoredExceptionHandler(CALL_LAST,VectoredHandlerSkip2);
h3 = AddVectoredExceptionHandler(CALL_LAST,VectoredHandler3);
IllegalInst();
CheckTest("Test2c",e,Actual);
RemoveVectoredExceptionHandler(h1);
RemoveVectoredExceptionHandler(h2);
RemoveVectoredExceptionHandler(h3);
CheckAllClear();
e[0]=2;e[1]=0xcc;e[2]=1;
h1 = AddVectoredExceptionHandler(CALL_LAST,VectoredHandler1);
h3 = AddVectoredExceptionHandler(CALL_FIRST,VectoredHandler3);
h2 = AddVectoredExceptionHandler(CALL_LAST,VectoredHandlerSkip2);
__try
{
IllegalInst();
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
// Should not make it to here.
e[0]=0;e[1]=0;e[2]=0;
CheckTest("Test2d-1",e,Actual);
}
CheckTest("Test2d-2",e,Actual);
RemoveVectoredExceptionHandler(h1);
RemoveVectoredExceptionHandler(h2);
RemoveVectoredExceptionHandler(h3);
CheckAllClear();
}
//Using a Vectored Exception Handler http://msdn.microsoft.com/en-us/library/windows/desktop/ms681411(v=vs.85).aspx
void main( )
{
Test1();
Test2();
getch();
}