source: trunk/src-cryptopp/trap.h

Last change on this file was e230cb0, checked in by David Stainton <dstainton415@…>, at 2016-10-12T13:27:29Z

Add cryptopp from tag CRYPTOPP_5_6_5

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