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