|
||||
File indexing completed on 2025-01-18 09:55:10
0001 // trap.h - written and placed in public domain by Jeffrey Walton. 0002 0003 /// \file trap.h 0004 /// \brief Debugging and diagnostic assertions 0005 /// \details <tt>CRYPTOPP_ASSERT</tt> is the library's debugging and diagnostic 0006 /// assertion. <tt>CRYPTOPP_ASSERT</tt> is enabled by <tt>CRYPTOPP_DEBUG</tt>, 0007 /// <tt>DEBUG</tt> or <tt>_DEBUG</tt>. 0008 /// \details <tt>CRYPTOPP_ASSERT</tt> raises a <tt>SIGTRAP</tt> (Unix) or calls 0009 /// <tt>DebugBreak()</tt> (Windows). 0010 /// \details <tt>CRYPTOPP_ASSERT</tt> is only in effect when the user requests a 0011 /// debug configuration. <tt>NDEBUG</tt> (or failure to define it) does not 0012 /// affect <tt>CRYPTOPP_ASSERT</tt>. 0013 /// \since Crypto++ 5.6.5 0014 /// \sa DebugTrapHandler, <A 0015 /// HREF="http://github.com/weidai11/cryptopp/issues/277">Issue 277</A>, 0016 /// <A HREF="http://seclists.org/oss-sec/2016/q3/520">CVE-2016-7420</A> 0017 0018 #ifndef CRYPTOPP_TRAP_H 0019 #define CRYPTOPP_TRAP_H 0020 0021 #include "config.h" 0022 0023 #if defined(CRYPTOPP_DEBUG) 0024 # include <iostream> 0025 # include <sstream> 0026 # if defined(UNIX_SIGNALS_AVAILABLE) 0027 # include "ossig.h" 0028 # elif defined(CRYPTOPP_WIN32_AVAILABLE) && !defined(__CYGWIN__) 0029 extern "C" __declspec(dllimport) void __stdcall DebugBreak(); 0030 extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent(); 0031 # endif 0032 #endif // CRYPTOPP_DEBUG 0033 0034 // ************** run-time assertion *************** 0035 0036 #if defined(CRYPTOPP_DOXYGEN_PROCESSING) 0037 /// \brief Debugging and diagnostic assertion 0038 /// \details <tt>CRYPTOPP_ASSERT</tt> is the library's debugging and diagnostic 0039 /// assertion. <tt>CRYPTOPP_ASSERT</tt> is enabled by the preprocessor macros 0040 /// <tt>CRYPTOPP_DEBUG</tt>, <tt>DEBUG</tt> or <tt>_DEBUG</tt>. 0041 /// \details <tt>CRYPTOPP_ASSERT</tt> raises a <tt>SIGTRAP</tt> (Unix) or calls 0042 /// <tt>DebugBreak()</tt> (Windows). <tt>CRYPTOPP_ASSERT</tt> is only in effect 0043 /// when the user explicitly requests a debug configuration. 0044 /// \details If you want to ensure <tt>CRYPTOPP_ASSERT</tt> is inert, then <em>do 0045 /// not</em> define <tt>CRYPTOPP_DEBUG</tt>, <tt>DEBUG</tt> or <tt>_DEBUG</tt>. 0046 /// Avoiding the defines means <tt>CRYPTOPP_ASSERT</tt> is preprocessed into an 0047 /// empty string. 0048 /// \details The traditional Posix define <tt>NDEBUG</tt> has no effect on 0049 /// <tt>CRYPTOPP_DEBUG</tt>, <tt>CRYPTOPP_ASSERT</tt> or DebugTrapHandler. 0050 /// \details An example of using CRYPTOPP_ASSERT and DebugTrapHandler is shown 0051 /// below. The library's test program, <tt>cryptest.exe</tt> (from test.cpp), 0052 /// exercises the structure: 0053 /// <pre> 0054 /// \#if defined(CRYPTOPP_DEBUG) && defined(UNIX_SIGNALS_AVAILABLE) 0055 /// static const DebugTrapHandler g_dummyHandler; 0056 /// \#endif 0057 /// 0058 /// int main(int argc, char* argv[]) 0059 /// { 0060 /// CRYPTOPP_ASSERT(argv != nullptr); 0061 /// ... 0062 /// } 0063 /// </pre> 0064 /// \since Crypto++ 5.6.5 0065 /// \sa DebugTrapHandler, SignalHandler, <A 0066 /// HREF="http://github.com/weidai11/cryptopp/issues/277">Issue 277</A>, 0067 /// <A HREF="http://seclists.org/oss-sec/2016/q3/520">CVE-2016-7420</A> 0068 # define CRYPTOPP_ASSERT(exp) { ... } 0069 #endif 0070 0071 #if defined(CRYPTOPP_DEBUG) 0072 # if defined(UNIX_SIGNALS_AVAILABLE) || defined(__CYGWIN__) 0073 # define CRYPTOPP_ASSERT(exp) { \ 0074 if (!(exp)) { \ 0075 std::ostringstream oss; \ 0076 oss << "Assertion failed: " << __FILE__ << "(" \ 0077 << __LINE__ << "): " << __func__ \ 0078 << std::endl; \ 0079 std::cout << std::flush; \ 0080 std::cerr << oss.str(); \ 0081 raise(SIGTRAP); \ 0082 } \ 0083 } 0084 # elif CRYPTOPP_DEBUG && defined(CRYPTOPP_WIN32_AVAILABLE) 0085 # define CRYPTOPP_ASSERT(exp) { \ 0086 if (!(exp)) { \ 0087 std::ostringstream oss; \ 0088 oss << "Assertion failed: " << __FILE__ << "(" \ 0089 << __LINE__ << "): " << __FUNCTION__ \ 0090 << std::endl; \ 0091 std::cout << std::flush; \ 0092 std::cerr << oss.str(); \ 0093 if (IsDebuggerPresent()) {DebugBreak();} \ 0094 } \ 0095 } 0096 # endif // Unix or Windows 0097 #endif // CRYPTOPP_DEBUG 0098 0099 // Remove CRYPTOPP_ASSERT in non-debug builds. 0100 #ifndef CRYPTOPP_ASSERT 0101 # define CRYPTOPP_ASSERT(exp) (void)0 0102 #endif 0103 0104 NAMESPACE_BEGIN(CryptoPP) 0105 0106 // ************** SIGTRAP handler *************** 0107 0108 #if (CRYPTOPP_DEBUG && defined(UNIX_SIGNALS_AVAILABLE)) || defined(CRYPTOPP_DOXYGEN_PROCESSING) 0109 /// \brief Default SIGTRAP handler 0110 /// \details DebugTrapHandler() can be used by a program to install an empty 0111 /// SIGTRAP handler. If present, the handler ensures there is a signal 0112 /// handler in place for <tt>SIGTRAP</tt> raised by 0113 /// <tt>CRYPTOPP_ASSERT</tt>. If <tt>CRYPTOPP_ASSERT</tt> raises 0114 /// <tt>SIGTRAP</tt> <em>without</em> a handler, then one of two things can 0115 /// occur. First, the OS might allow the program to continue. Second, the OS 0116 /// might terminate the program. OS X allows the program to continue, while 0117 /// some Linuxes terminate the program. 0118 /// \details If DebugTrapHandler detects another handler in place, then it will 0119 /// not install a handler. This ensures a debugger can gain control of the 0120 /// <tt>SIGTRAP</tt> signal without contention. It also allows multiple 0121 /// DebugTrapHandler to be created without contentious or unusual behavior. 0122 /// Though multiple DebugTrapHandler can be created, a program should only 0123 /// create one, if needed. 0124 /// \details A DebugTrapHandler is subject to C++ static initialization 0125 /// [dis]order. If you need to install a handler and it must be installed 0126 /// early, then reference the code associated with 0127 /// <tt>CRYPTOPP_INIT_PRIORITY</tt> in cryptlib.cpp and cpu.cpp. 0128 /// \details If you want to ensure <tt>CRYPTOPP_ASSERT</tt> is inert, then 0129 /// <em>do not</em> define <tt>CRYPTOPP_DEBUG</tt>, <tt>DEBUG</tt> or 0130 /// <tt>_DEBUG</tt>. Avoiding the defines means <tt>CRYPTOPP_ASSERT</tt> 0131 /// is processed into <tt>((void)0)</tt>. 0132 /// \details The traditional Posix define <tt>NDEBUG</tt> has no effect on 0133 /// <tt>CRYPTOPP_DEBUG</tt>, <tt>CRYPTOPP_ASSERT</tt> or DebugTrapHandler. 0134 /// \details An example of using \ref CRYPTOPP_ASSERT "CRYPTOPP_ASSERT" and 0135 /// DebugTrapHandler is shown below. The library's test program, 0136 /// <tt>cryptest.exe</tt> (from test.cpp), exercises the structure: 0137 /// <pre> 0138 /// \#if defined(CRYPTOPP_DEBUG) && defined(UNIX_SIGNALS_AVAILABLE) 0139 /// const DebugTrapHandler g_dummyHandler; 0140 /// \#endif 0141 /// 0142 /// int main(int argc, char* argv[]) 0143 /// { 0144 /// CRYPTOPP_ASSERT(argv != nullptr); 0145 /// ... 0146 /// } 0147 /// </pre> 0148 /// \since Crypto++ 5.6.5 0149 /// \sa \ref CRYPTOPP_ASSERT "CRYPTOPP_ASSERT", SignalHandler, <A 0150 /// HREF="http://github.com/weidai11/cryptopp/issues/277">Issue 277</A>, 0151 /// <A HREF="http://seclists.org/oss-sec/2016/q3/520">CVE-2016-7420</A> 0152 0153 #if defined(CRYPTOPP_DOXYGEN_PROCESSING) 0154 class DebugTrapHandler : public SignalHandler<SIGTRAP, false> { }; 0155 #else 0156 typedef SignalHandler<SIGTRAP, false> DebugTrapHandler; 0157 #endif 0158 0159 #endif // Linux, Unix and Documentation 0160 0161 NAMESPACE_END 0162 0163 #endif // CRYPTOPP_TRAP_H
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |