acme
Foundational cross-platform layer of the ca2 framework
Loading...
Searching...
No Matches
trap.h
1/*
2 Copyright (ca) 2001
3 Author: Konstantin Boukreev
4 E-mail: [email protected]
5 Created: 07.11.2001 14:17:21
6 Version: 1.1.0
7
8 Permission to use, copy, modify, distribute and sell this software
9 and its documentation for any purpose is hereby granted without fee,
10 provided that the above copyright notice appear in all copies and
11 that both that copyright notice and this permission notice appear
12 in supporting documentation. Konstantin Boukreev makes no representations
13 about the suitability of this software for any purpose.
14 It is provided "as is" without express or implied warranty.
15
16
17 wrapper class for SetUnhandledExceptionFilter API
18*/
19
20#pragma once
21
22#include "ca_Aux2.h"
23
25{
26 long operator () (EXCEPTION_POINTERS *)
27 { return EXCEPTION_CONTINUE_SEARCH; }
28};
29
30template <typename P>
31class exception_trap :
32 public CAuxStdThunk<exception_trap>
33{
34public:
35 typedef P Policy;
36
37protected:
38 LPTOP_LEVEL_EXCEPTION_FILTER m_fn_prev_filter;
39 Policy m_policy;
40
41public:
42 exception_trap(bool, const Policy& point = Policy());
43 ~exception_trap();
44
45 void install(bool);
46
47 bool is_alive () const {return m_fn_prev_filter != 0;}
48 Policy& get_policy() {return m_policy;}
49
50private:
51 long __stdcall filter (EXCEPTION_POINTERS *);
52
53 static LPTOP_LEVEL_EXCEPTION_FILTER fake ()
54 {return (LPTOP_LEVEL_EXCEPTION_FILTER)0xffffffff;}
55};
56
58
59template <typename P>
60inline exception_trap<P>::exception_trap(bool b, const Policy& point)
61 : m_fn_prev_filter(0), m_policy(point)
62{
63 InitThunk((TMFP)filter, this);
64 install(b);
65}
66
67template <typename P>
68inline exception_trap<P>::~exception_trap()
69{
70 install(false);
71}
72
73template <typename P>
74inline void exception_trap<P>::install(bool b)
75{
76 if (is_alive())
77 {
78 SetUnhandledExceptionFilter(m_fn_prev_filter == fake() ? 0 : m_fn_prev_filter);
79 m_fn_prev_filter = 0;
80 }
81
82 if (b)
83 {
84 m_fn_prev_filter = SetUnhandledExceptionFilter
85 ((LPTOP_LEVEL_EXCEPTION_FILTER)GetThunk());
86 m_fn_prev_filter = !m_fn_prev_filter ? fake() : m_fn_prev_filter;
87 }
88}
89
90template <typename P>
91inline long __stdcall exception_trap<P>::filter(EXCEPTION_POINTERS * pex)
92{
93 if (EXCEPTION_STACK_OVERFLOW == pex->ExceptionRecord->ExceptionCode)
94 {
95 // stack overflow occurred,
96 // unfortunately it's unable to do anything useful in this case
97 return EXCEPTION_CONTINUE_SEARCH;
98 }
99
100 long r = EXCEPTION_CONTINUE_SEARCH;
101
102 __try
103 {
104 r = m_policy(pex);
105
106 if (r == EXCEPTION_CONTINUE_SEARCH &&
107 (m_fn_prev_filter && m_fn_prev_filter != fake()) &&
108 !IsBadCodePtr((FARPROC)m_fn_prev_filter))
109 {
110 r = m_fn_prev_filter(pex);
111 }
112 }
113 __except(EXCEPTION_EXECUTE_HANDLER)
114 {
115 r = EXCEPTION_CONTINUE_SEARCH;
116 }
117
118 return r;
119}
120
Definition trap.h:25