Attached is the meat and potatoes of the proposed patch. It omits all the 
assert -> CRYPTOPP_ASSERT changes.

It works great outside and under the debugger. The program does not crash 
with a SIGABRT at critical times during the debug cycle.

On Wednesday, July 15, 2015 at 4:27:04 PM UTC-4, Jeffrey Walton wrote:
>
> I'm catching an assert when running with -DDEBUG (i.e., not -DNDEBUG):
>
>     cryptest.exe: misc.h:703: T CryptoPP::rotlMod(T, unsigned int)
>         [with T = unsigned int]: Assertion `y <= 255' failed.
>
> The assert is fine. I adore asserts, because they create "self debugging 
> code". When the code tells me where the problem is, I don't have to spend 
> time under a debugger. In code under my purview in real life, we make debug 
> instrumentation a security gate because it so helpful. If code does not 
> have the instrumentation, it cannot be checked in.
>
> The issue I have is Posix's default behavior of "lets crash the program 
> while the developer is debugging it". Its completely useless behavior.
>

diff --git a/config.h b/config.h
index e359729..9c4fd9e 100644
--- a/config.h
+++ b/config.h
@@ -53,6 +53,11 @@
 #define PREFER_BERKELEY_STYLE_SOCKETS
 // #define PREFER_WINDOWS_STYLE_SOCKETS
 
+// Undefine this in Debug builds if you don't want a SIGTRAP handler 
installed.
+// The cryptest program will install the handler for CRYPTOPP_ASSERT which 
+// raises SIGTRAP. Its does not affect Release builds when NDEBUG is 
defined.
+#define CRYPTOPP_INSTALL_SIGTRAP_HANDLER
+
 // set the name of Rijndael cipher, was "Rijndael" before version 5.3
 #define CRYPTOPP_RIJNDAEL_NAME "AES"
 
diff --git a/test.cpp b/test.cpp
index a3250a8..0dd5937 100644
--- a/test.cpp
+++ b/test.cpp
@@ -56,6 +56,12 @@ USING_NAMESPACE(std)
 
 const int MAX_PHRASE_LENGTH=250;
 
+#if defined(CRYPTOPP_INSTALL_SIGTRAP_HANDLER) && !defined(NDEBUG)
+#if defined(CRYPTOPP_UNIX_AVAILABLE)
+# include <signal.h>  // SIGTRAP handler
+#endif
+#endif
+
 void RegisterFactories();
 
 void GenerateRSAKey(unsigned int keyLength, const char *privFilename, 
const char *pubFilename, const char *seed);
@@ -238,7 +244,7 @@ int CRYPTOPP_API main(int argc, char *argv[])
 
             // compute MAC
             member_ptr<MessageAuthenticationCode> 
pMac(NewIntegrityCheckingMAC());
-            assert(pMac->DigestSize() == sizeof(mac));
+            CRYPTOPP_ASSERT(pMac->DigestSize() == sizeof(mac));
             MeterFilter f(new HashFilter(*pMac, new ArraySink(mac, 
sizeof(mac))));
             f.AddRangeToSkip(0, checksumPos, 4);
             f.AddRangeToSkip(0, certificateTableDirectoryPos, 8);
@@ -369,6 +375,55 @@ int CRYPTOPP_API main(int argc, char *argv[])
     }
 }
 
+#if defined(CRYPTOPP_INSTALL_SIGTRAP_HANDLER) && !defined(NDEBUG)
+#if defined(CRYPTOPP_UNIX_AVAILABLE)
+// Add a SIGTRAP handler for *nix.
+struct DebugTrapHandler
+{
+    DebugTrapHandler()
+    {
+        // 
http://pubs.opengroup.org/onlinepubs/007908799/xsh/sigaction.html
+        struct sigaction old_handler, new_handler;
+        memset(&old_handler, 0x00, sizeof(old_handler));
+        memset(&new_handler, 0x00, sizeof(new_handler));
+
+        do
+        {
+            int ret = 0;
+
+            ret = sigaction (SIGTRAP, NULL, &old_handler);
+            if (ret != 0) break; // Failed
+
+            // Don't step on another's handler
+            if (old_handler.sa_handler != NULL) break;
+
+            // Set up the structure to specify the null action.
+            new_handler.sa_handler = &DebugTrapHandler::NullHandler;
+            new_handler.sa_flags = 0;
+
+            ret = sigemptyset (&new_handler.sa_mask);
+            if (ret != 0) break; // Failed
+
+            // Install it
+            ret = sigaction (SIGTRAP, &new_handler, NULL);
+            if (ret != 0) break; // Failed
+
+        } while(0);
+    }
+
+    static void NullHandler(int /*unused*/) { }
+};
+
+#if __GNUC__
+// Specify a relatively low priority to make sure we run before other CTORs
+// 
http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html#C_002b_002b-Attributes
+static const DebugTrapHandler g_dummyHandler __attribute__ ((init_priority 
(110)));
+#else
+static const DebugTrapHandler g_dummyHandler;
+#endif // __GNUC__
+#endif // CRYPTOPP_UNIX_AVAILABLE
+#endif // CRYPTOPP_INSTALL_SIGTRAP_HANDLER and not NDEBUG
+
 void FIPS140_GenerateRandomFiles()
 {
 #ifdef OS_RNG_AVAILABLE
 
***** BEGIN cat of trap.h *****

// trap.h - written and placed in public domain by Jeffrey Walton.
//          Copyright assigned to Crypto++ project

#ifndef CRYPTOPP_TRAP_H
#define CRYPTOPP_TRAP_H

#ifndef NDEBUG
#ifdef CRYPTOPP_UNIX_AVAILABLE
# include <iostream>
# include <sstream>
# include <signal.h>
#endif // CRYPTOPP_UNIX_AVAILABLE
#endif // NDEBUG

#include <cassert>

// ************** run-time assertion ***************

// Linux and Unix
#if !defined(NDEBUG) && defined(CRYPTOPP_UNIX_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);                                             \
    }                                                             \
  }
// Fallback to original behavior (including for NDEBUG)
#else
#  define CRYPTOPP_ASSERT(exp) assert(exp)
#endif // NDEBUG

#endif // CRYPTOPP_TRAP_H

***** END cat of trap.h *****
 

-- 
-- 
You received this message because you are subscribed to the "Crypto++ Users" 
Google Group.
To unsubscribe, send an email to [email protected].
More information about Crypto++ and this group is available at 
http://www.cryptopp.com.
--- 
You received this message because you are subscribed to the Google Groups 
"Crypto++ Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.
diff --git a/config.h b/config.h
index e359729..9c4fd9e 100644
--- a/config.h
+++ b/config.h
@@ -53,6 +53,11 @@
 #define PREFER_BERKELEY_STYLE_SOCKETS
 // #define PREFER_WINDOWS_STYLE_SOCKETS
 
+// Undefine this in Debug builds if you don't want a SIGTRAP handler installed.
+// The cryptest program will install the handler for CRYPTOPP_ASSERT which 
+// raises SIGTRAP. Its does not affect Release builds when NDEBUG is defined.
+#define CRYPTOPP_INSTALL_SIGTRAP_HANDLER
+
 // set the name of Rijndael cipher, was "Rijndael" before version 5.3
 #define CRYPTOPP_RIJNDAEL_NAME "AES"
 
diff --git a/test.cpp b/test.cpp
index a3250a8..0dd5937 100644
--- a/test.cpp
+++ b/test.cpp
@@ -56,6 +56,12 @@ USING_NAMESPACE(std)
 
 const int MAX_PHRASE_LENGTH=250;
 
+#if defined(CRYPTOPP_INSTALL_SIGTRAP_HANDLER) && !defined(NDEBUG)
+#if defined(CRYPTOPP_UNIX_AVAILABLE)
+# include <signal.h>  // SIGTRAP handler
+#endif
+#endif
+
 void RegisterFactories();
 
 void GenerateRSAKey(unsigned int keyLength, const char *privFilename, const char *pubFilename, const char *seed);
@@ -238,7 +244,7 @@ int CRYPTOPP_API main(int argc, char *argv[])
 
 			// compute MAC
 			member_ptr<MessageAuthenticationCode> pMac(NewIntegrityCheckingMAC());
-			assert(pMac->DigestSize() == sizeof(mac));
+			CRYPTOPP_ASSERT(pMac->DigestSize() == sizeof(mac));
 			MeterFilter f(new HashFilter(*pMac, new ArraySink(mac, sizeof(mac))));
 			f.AddRangeToSkip(0, checksumPos, 4);
 			f.AddRangeToSkip(0, certificateTableDirectoryPos, 8);
@@ -369,6 +375,55 @@ int CRYPTOPP_API main(int argc, char *argv[])
 	}
 }
 
+#if defined(CRYPTOPP_INSTALL_SIGTRAP_HANDLER) && !defined(NDEBUG)
+#if defined(CRYPTOPP_UNIX_AVAILABLE)
+// Add a SIGTRAP handler for *nix.
+struct DebugTrapHandler
+{
+	DebugTrapHandler()
+	{
+		// http://pubs.opengroup.org/onlinepubs/007908799/xsh/sigaction.html
+		struct sigaction old_handler, new_handler;
+		memset(&old_handler, 0x00, sizeof(old_handler));
+		memset(&new_handler, 0x00, sizeof(new_handler));
+
+		do
+		{
+			int ret = 0;
+
+			ret = sigaction (SIGTRAP, NULL, &old_handler);
+			if (ret != 0) break; // Failed
+
+			// Don't step on another's handler
+			if (old_handler.sa_handler != NULL) break;
+
+			// Set up the structure to specify the null action.
+			new_handler.sa_handler = &DebugTrapHandler::NullHandler;
+			new_handler.sa_flags = 0;
+
+			ret = sigemptyset (&new_handler.sa_mask);
+			if (ret != 0) break; // Failed
+
+			// Install it
+			ret = sigaction (SIGTRAP, &new_handler, NULL);
+			if (ret != 0) break; // Failed
+
+		} while(0);
+	}
+
+	static void NullHandler(int /*unused*/) { }
+};
+
+#if __GNUC__
+// Specify a relatively low priority to make sure we run before other CTORs
+// http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html#C_002b_002b-Attributes
+static const DebugTrapHandler g_dummyHandler __attribute__ ((init_priority (110)));
+#else
+static const DebugTrapHandler g_dummyHandler;
+#endif // __GNUC__
+#endif // CRYPTOPP_UNIX_AVAILABLE
+#endif // CRYPTOPP_INSTALL_SIGTRAP_HANDLER and not NDEBUG
+
 void FIPS140_GenerateRandomFiles()
 {
 #ifdef OS_RNG_AVAILABLE
@@ -545,7 +600,7 @@ void DecryptFile(const char *in, const char *out, const char *passPhrase)
 
 void SecretShareFile(int threshold, int nShares, const char *filename, const char *seed)
 {
-	assert(nShares<=1000);
+	CRYPTOPP_ASSERT(nShares<=1000);
 
 	RandomPool rng;
 	rng.IncorporateEntropy((byte *)seed, strlen(seed));
@@ -573,7 +628,7 @@ void SecretShareFile(int threshold, int nShares, const char *filename, const cha
 
 void SecretRecoverFile(int threshold, const char *outFilename, char *const *inFilenames)
 {
-	assert(threshold<=1000);
+	CRYPTOPP_ASSERT(threshold<=1000);
 
 	SecretRecovery recovery(threshold, new FileSink(outFilename));
 
@@ -598,7 +653,7 @@ void SecretRecoverFile(int threshold, const char *outFilename, char *const *inFi
 
 void InformationDisperseFile(int threshold, int nShares, const char *filename)
 {
-	assert(nShares<=1000);
+	CRYPTOPP_ASSERT(nShares<=1000);
 
 	ChannelSwitch *channelSwitch;
 	FileSource source(filename, false, new InformationDispersal(threshold, nShares, channelSwitch = new ChannelSwitch));
@@ -623,7 +678,7 @@ void InformationDisperseFile(int threshold, int nShares, const char *filename)
 
 void InformationRecoverFile(int threshold, const char *outFilename, char *const *inFilenames)
 {
-	assert(threshold<=1000);
+	CRYPTOPP_ASSERT(threshold<=1000);
 
 	InformationRecovery recovery(threshold, new FileSink(outFilename));
 
***** BEGIN cat of trap.h *****

// trap.h - written and placed in public domain by Jeffrey Walton.
//          Copyright assigned to Crypto++ project

#ifndef CRYPTOPP_TRAP_H
#define CRYPTOPP_TRAP_H

#ifndef NDEBUG
#ifdef CRYPTOPP_UNIX_AVAILABLE
# include <iostream>
# include <sstream>
# include <signal.h>
#endif // CRYPTOPP_UNIX_AVAILABLE
#endif // NDEBUG

#include <cassert>

// ************** run-time assertion ***************

// Linux and Unix
#if !defined(NDEBUG) && defined(CRYPTOPP_UNIX_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);                                             \
    }                                                             \
  }
// Fallback to original behavior (including for NDEBUG)
#else
#  define CRYPTOPP_ASSERT(exp) assert(exp)
#endif // NDEBUG

#endif // CRYPTOPP_TRAP_H

***** END cat of trap.h *****

Reply via email to