# if defined(UNIX_SIGNALS_AVAILABLE)
# include "ossig.h"
# elif defined(CRYPTOPP_WIN32_AVAILABLE) && !defined(__CYGWIN__)
extern "C" __declspec(dllimport) void __stdcall DebugBreak();
extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
# endif
#endif // CRYPTOPP_DEBUG
// ************** run-time assertion ***************
#if defined(CRYPTOPP_DOXYGEN_PROCESSING)
//! \brief Debugging and diagnostic assertion
//! \details CRYPTOPP_ASSERT is the library's debugging and diagnostic assertion. CRYPTOPP_ASSERT
//! is enabled by the preprocessor macros CRYPTOPP_DEBUG, DEBUG or _DEBUG.
//! \details CRYPTOPP_ASSERT raises a SIGTRAP (Unix) or calls DebugBreak() (Windows).
//! CRYPTOPP_ASSERT is only in effect when the user explicitly requests a debug configuration.
//! \details If you want to ensure CRYPTOPP_ASSERT is inert, then do not define
//! CRYPTOPP_DEBUG, DEBUG or _DEBUG. Avoiding the defines means CRYPTOPP_ASSERT
//! is preprocessed into an empty string.
//! \details The traditional Posix define NDEBUG has no effect on CRYPTOPP_DEBUG, CRYPTOPP_ASSERT
//! or DebugTrapHandler.
//! \details An example of using \ref CRYPTOPP_ASSERT "CRYPTOPP_ASSERT" and DebugTrapHandler is shown below. The library's
//! test program, cryptest.exe (from test.cpp), exercises the structure:
//!
//! #if defined(CRYPTOPP_DEBUG) && defined(UNIX_SIGNALS_AVAILABLE)
//! static const DebugTrapHandler g_dummyHandler;
//! #endif
//!
//! int main(int argc, char* argv[])
//! {
//! CRYPTOPP_ASSERT(argv != nullptr);
//! ...
//! }
//!
//! \since Crypto++ 5.6.5
//! \sa DebugTrapHandler, SignalHandler, Issue 277,
//! CVE-2016-7420
# define CRYPTOPP_ASSERT(exp) { ... }
#endif
#if defined(CRYPTOPP_DEBUG) && defined(UNIX_SIGNALS_AVAILABLE)
# define CRYPTOPP_ASSERT(exp) { \
if (!(exp)) { \
std::ostringstream oss; \
oss << "Assertion failed: " << (char*)(__FILE__) << "(" \
<< (int)(__LINE__) << "): " << (char*)(__func__) \
<< std::endl; \
std::cerr << oss.str(); \
raise(SIGTRAP); \
} \
}
#elif CRYPTOPP_DEBUG && defined(CRYPTOPP_WIN32_AVAILABLE) && !defined(__CYGWIN__)
# define CRYPTOPP_ASSERT(exp) { \
if (!(exp)) { \
std::ostringstream oss; \
oss << "Assertion failed: " << (char*)(__FILE__) << "(" \
<< (int)(__LINE__) << "): " << (char*)(__FUNCTION__) \
<< std::endl; \
std::cerr << oss.str(); \
if (IsDebuggerPresent()) {DebugBreak();} \
} \
}
#endif // DEBUG and Unix or Windows
// Remove CRYPTOPP_ASSERT in non-debug builds.
// Can't use CRYPTOPP_UNUSED due to circular dependency
#ifndef CRYPTOPP_ASSERT
# define CRYPTOPP_ASSERT(exp) (void)0
#endif
NAMESPACE_BEGIN(CryptoPP)
// ************** SIGTRAP handler ***************
#if (CRYPTOPP_DEBUG && defined(UNIX_SIGNALS_AVAILABLE)) || defined(CRYPTOPP_DOXYGEN_PROCESSING)
//! \brief Default SIGTRAP handler
//! \details DebugTrapHandler() can be used by a program to install an empty SIGTRAP handler. If present,
//! the handler ensures there is a signal handler in place for SIGTRAP raised by
//! CRYPTOPP_ASSERT. If CRYPTOPP_ASSERT raises SIGTRAP without
//! a handler, then one of two things can occur. First, the OS might allow the program
//! to continue. Second, the OS might terminate the program. OS X allows the program to continue, while
//! some Linuxes terminate the program.
//! \details If DebugTrapHandler detects another handler in place, then it will not install a handler. This
//! ensures a debugger can gain control of the SIGTRAP signal without contention. It also allows multiple
//! DebugTrapHandler to be created without contentious or unusual behavior. Though multiple DebugTrapHandler can be
//! created, a program should only create one, if needed.
//! \details A DebugTrapHandler is subject to C++ static initialization [dis]order. If you need to install a handler
//! and it must be installed early, then reference the code associated with CRYPTOPP_INIT_PRIORITY in
//! cryptlib.cpp and cpu.cpp.
//! \details If you want to ensure CRYPTOPP_ASSERT is inert, then do not define
//! CRYPTOPP_DEBUG, DEBUG or _DEBUG. Avoiding the defines means CRYPTOPP_ASSERT
//! is processed into ((void)(exp)).
//! \details The traditional Posix define NDEBUG has no effect on CRYPTOPP_DEBUG, CRYPTOPP_ASSERT
//! or DebugTrapHandler.
//! \details An example of using \ref CRYPTOPP_ASSERT "CRYPTOPP_ASSERT" and DebugTrapHandler is shown below. The library's
//! test program, cryptest.exe (from test.cpp), exercises the structure:
//!
//! #if defined(CRYPTOPP_DEBUG) && defined(UNIX_SIGNALS_AVAILABLE)
//! static const DebugTrapHandler g_dummyHandler;
//! #endif
//!
//! int main(int argc, char* argv[])
//! {
//! CRYPTOPP_ASSERT(argv != nullptr);
//! ...
//! }
//!
//! \since Crypto++ 5.6.5
//! \sa \ref CRYPTOPP_ASSERT "CRYPTOPP_ASSERT", SignalHandler, Issue 277,
//! CVE-2016-7420
#if defined(CRYPTOPP_DOXYGEN_PROCESSING)
class DebugTrapHandler : public SignalHandler { };
#else
typedef SignalHandler DebugTrapHandler;
#endif
#endif // Linux, Unix and Documentation
NAMESPACE_END
#endif // CRYPTOPP_TRAP_H