Crypto++
8.6
Free C++ class library of cryptographic schemes
trap.h
Go to the documentation of this file.
1
// trap.h - written and placed in public domain by Jeffrey Walton.
2
3
/// \file trap.h
4
/// \brief Debugging and diagnostic assertions
5
/// \details <tt>CRYPTOPP_ASSERT</tt> is the library's debugging and diagnostic
6
/// assertion. <tt>CRYPTOPP_ASSERT</tt> is enabled by <tt>CRYPTOPP_DEBUG</tt>,
7
/// <tt>DEBUG</tt> or <tt>_DEBUG</tt>.
8
/// \details <tt>CRYPTOPP_ASSERT</tt> raises a <tt>SIGTRAP</tt> (Unix) or calls
9
/// <tt>DebugBreak()</tt> (Windows).
10
/// \details <tt>CRYPTOPP_ASSERT</tt> is only in effect when the user requests a
11
/// debug configuration. <tt>NDEBUG</tt> (or failure to define it) does not
12
/// affect <tt>CRYPTOPP_ASSERT</tt>.
13
/// \since Crypto++ 5.6.5
14
/// \sa DebugTrapHandler, <A
15
/// HREF="http://github.com/weidai11/cryptopp/issues/277">Issue 277</A>,
16
/// <A HREF="http://seclists.org/oss-sec/2016/q3/520">CVE-2016-7420</A>
17
18
#ifndef CRYPTOPP_TRAP_H
19
#define CRYPTOPP_TRAP_H
20
21
#include "
config.h
"
22
23
#if defined(CRYPTOPP_DEBUG)
24
# include <iostream>
25
# include <sstream>
26
# if defined(UNIX_SIGNALS_AVAILABLE)
27
# include "
ossig.h
"
28
# elif defined(CRYPTOPP_WIN32_AVAILABLE) && !defined(__CYGWIN__)
29
extern
"C"
__declspec(dllimport)
void
__stdcall DebugBreak();
30
extern
"C"
__declspec(dllimport)
int
__stdcall IsDebuggerPresent();
31
# endif
32
#endif // CRYPTOPP_DEBUG
33
34
// ************** run-time assertion ***************
35
36
#if defined(CRYPTOPP_DOXYGEN_PROCESSING)
37
/// \brief Debugging and diagnostic assertion
38
/// \details <tt>CRYPTOPP_ASSERT</tt> is the library's debugging and diagnostic
39
/// assertion. <tt>CRYPTOPP_ASSERT</tt> is enabled by the preprocessor macros
40
/// <tt>CRYPTOPP_DEBUG</tt>, <tt>DEBUG</tt> or <tt>_DEBUG</tt>.
41
/// \details <tt>CRYPTOPP_ASSERT</tt> raises a <tt>SIGTRAP</tt> (Unix) or calls
42
/// <tt>DebugBreak()</tt> (Windows). <tt>CRYPTOPP_ASSERT</tt> is only in effect
43
/// when the user explicitly requests a debug configuration.
44
/// \details If you want to ensure <tt>CRYPTOPP_ASSERT</tt> is inert, then <em>do
45
/// not</em> define <tt>CRYPTOPP_DEBUG</tt>, <tt>DEBUG</tt> or <tt>_DEBUG</tt>.
46
/// Avoiding the defines means <tt>CRYPTOPP_ASSERT</tt> is preprocessed into an
47
/// empty string.
48
/// \details The traditional Posix define <tt>NDEBUG</tt> has no effect on
49
/// <tt>CRYPTOPP_DEBUG</tt>, <tt>CRYPTOPP_ASSERT</tt> or DebugTrapHandler.
50
/// \details An example of using CRYPTOPP_ASSERT and DebugTrapHandler is shown
51
/// below. The library's test program, <tt>cryptest.exe</tt> (from test.cpp),
52
/// exercises the structure:
53
/// <pre>
54
/// \#if defined(CRYPTOPP_DEBUG) && defined(UNIX_SIGNALS_AVAILABLE)
55
/// static const DebugTrapHandler g_dummyHandler;
56
/// \#endif
57
///
58
/// int main(int argc, char* argv[])
59
/// {
60
/// CRYPTOPP_ASSERT(argv != nullptr);
61
/// ...
62
/// }
63
/// </pre>
64
/// \since Crypto++ 5.6.5
65
/// \sa DebugTrapHandler, SignalHandler, <A
66
/// HREF="http://github.com/weidai11/cryptopp/issues/277">Issue 277</A>,
67
/// <A HREF="http://seclists.org/oss-sec/2016/q3/520">CVE-2016-7420</A>
68
# define CRYPTOPP_ASSERT(exp) { ... }
69
#endif
70
71
#if defined(CRYPTOPP_DEBUG)
72
# if defined(UNIX_SIGNALS_AVAILABLE) || defined(__CYGWIN__)
73
# define CRYPTOPP_ASSERT(exp) { \
74
if (!(exp)) { \
75
std::ostringstream oss; \
76
oss << "Assertion failed: " << __FILE__ << "(" \
77
<< __LINE__ << "): " << __func__ \
78
<< std::endl; \
79
std::cout << std::flush; \
80
std::cerr << oss.str(); \
81
raise(SIGTRAP); \
82
} \
83
}
84
# elif CRYPTOPP_DEBUG && defined(CRYPTOPP_WIN32_AVAILABLE)
85
# define CRYPTOPP_ASSERT(exp) { \
86
if (!(exp)) { \
87
std::ostringstream oss; \
88
oss << "Assertion failed: " << __FILE__ << "(" \
89
<< __LINE__ << "): " << __FUNCTION__ \
90
<< std::endl; \
91
std::cout << std::flush; \
92
std::cerr << oss.str(); \
93
if (IsDebuggerPresent()) {DebugBreak();} \
94
} \
95
}
96
# endif // Unix or Windows
97
#endif // CRYPTOPP_DEBUG
98
99
// Remove CRYPTOPP_ASSERT in non-debug builds.
100
#ifndef CRYPTOPP_ASSERT
101
# define CRYPTOPP_ASSERT(exp) (void)0
102
#endif
103
104
NAMESPACE_BEGIN(
CryptoPP
)
105
106
// ************** SIGTRAP handler ***************
107
108
#if (CRYPTOPP_DEBUG && defined(UNIX_SIGNALS_AVAILABLE)) || defined(CRYPTOPP_DOXYGEN_PROCESSING)
109
/// \brief Default SIGTRAP handler
110
/// \details DebugTrapHandler() can be used by a program to install an empty
111
/// SIGTRAP handler. If present, the handler ensures there is a signal
112
/// handler in place for <tt>SIGTRAP</tt> raised by
113
/// <tt>CRYPTOPP_ASSERT</tt>. If <tt>CRYPTOPP_ASSERT</tt> raises
114
/// <tt>SIGTRAP</tt> <em>without</em> a handler, then one of two things can
115
/// occur. First, the OS might allow the program to continue. Second, the OS
116
/// might terminate the program. OS X allows the program to continue, while
117
/// some Linuxes terminate the program.
118
/// \details If DebugTrapHandler detects another handler in place, then it will
119
/// not install a handler. This ensures a debugger can gain control of the
120
/// <tt>SIGTRAP</tt> signal without contention. It also allows multiple
121
/// DebugTrapHandler to be created without contentious or unusual behavior.
122
/// Though multiple DebugTrapHandler can be created, a program should only
123
/// create one, if needed.
124
/// \details A DebugTrapHandler is subject to C++ static initialization
125
/// [dis]order. If you need to install a handler and it must be installed
126
/// early, then reference the code associated with
127
/// <tt>CRYPTOPP_INIT_PRIORITY</tt> in cryptlib.cpp and cpu.cpp.
128
/// \details If you want to ensure <tt>CRYPTOPP_ASSERT</tt> is inert, then
129
/// <em>do not</em> define <tt>CRYPTOPP_DEBUG</tt>, <tt>DEBUG</tt> or
130
/// <tt>_DEBUG</tt>. Avoiding the defines means <tt>CRYPTOPP_ASSERT</tt>
131
/// is processed into <tt>((void)0)</tt>.
132
/// \details The traditional Posix define <tt>NDEBUG</tt> has no effect on
133
/// <tt>CRYPTOPP_DEBUG</tt>, <tt>CRYPTOPP_ASSERT</tt> or DebugTrapHandler.
134
/// \details An example of using \ref CRYPTOPP_ASSERT "CRYPTOPP_ASSERT" and
135
/// DebugTrapHandler is shown below. The library's test program,
136
/// <tt>cryptest.exe</tt> (from test.cpp), exercises the structure:
137
/// <pre>
138
/// \#if defined(CRYPTOPP_DEBUG) && defined(UNIX_SIGNALS_AVAILABLE)
139
/// const DebugTrapHandler g_dummyHandler;
140
/// \#endif
141
///
142
/// int main(int argc, char* argv[])
143
/// {
144
/// CRYPTOPP_ASSERT(argv != nullptr);
145
/// ...
146
/// }
147
/// </pre>
148
/// \since Crypto++ 5.6.5
149
/// \sa \ref CRYPTOPP_ASSERT "CRYPTOPP_ASSERT", SignalHandler, <A
150
/// HREF="http://github.com/weidai11/cryptopp/issues/277">Issue 277</A>,
151
/// <A HREF="http://seclists.org/oss-sec/2016/q3/520">CVE-2016-7420</A>
152
153
#if defined(CRYPTOPP_DOXYGEN_PROCESSING)
154
class
DebugTrapHandler
:
public
SignalHandler
<SIGTRAP, false> { };
155
#else
156
typedef
SignalHandler<SIGTRAP, false>
DebugTrapHandler
;
157
#endif
158
159
#endif // Linux, Unix and Documentation
160
161
NAMESPACE_END
162
163
#endif // CRYPTOPP_TRAP_H
SignalHandler
Signal handler for Linux and Unix compatibles.
Definition:
ossig.h:58
ossig.h
Utility class for trapping OS signals.
CryptoPP
Crypto++ library namespace.
config.h
Library configuration file.
DebugTrapHandler
Default SIGTRAP handler.
Definition:
trap.h:154
Generated on Sun May 29 2022 18:23:23 for Crypto++ by
1.8.17