BLACK_AUDIT macro for paranoid checks on data consistency

Summary:
Triggers a breakpoint when the debugger is attached to a debug build. Otherwise, logs a warning.

Related: T101

Reviewers: kbasan, rwinklmeier

Reviewed By: kbasan

Subscribers: jenkins

Tags: #swift_pilot_client

Differential Revision: https://dev.swift-project.org/D35
This commit is contained in:
Mathew Sutcliffe
2017-07-07 14:25:52 +01:00
parent 7d7ce055ef
commit c790e344ac
2 changed files with 37 additions and 18 deletions

View File

@@ -9,7 +9,6 @@
#include "blackmisc/verify.h" #include "blackmisc/verify.h"
#include "blackmisc/logmessage.h" #include "blackmisc/logmessage.h"
#include <QtGlobal> #include <QtGlobal>
#ifdef BLACK_USE_CRASHPAD #ifdef BLACK_USE_CRASHPAD
@@ -18,7 +17,7 @@
#if defined(Q_CC_MSVC) #if defined(Q_CC_MSVC)
#include <intrin.h> #include <intrin.h>
#elif defined(Q_OS_UNIX) #include <windows.h>
#endif #endif
#if defined(Q_CC_CLANG) #if defined(Q_CC_CLANG)
@@ -32,14 +31,36 @@ namespace BlackMisc
namespace Private namespace Private
{ {
// cppcheck-suppress unusedFunction // cppcheck-suppress unusedFunction
void failedVerify(const char *condition, const char *filename, int line, const char *context, const char *message) void failedVerify(const char *condition, const char *filename, int line, const char *context, const char *message, bool audit)
{ {
Q_UNUSED(condition); Q_UNUSED(condition);
Q_UNUSED(filename); Q_UNUSED(filename);
Q_UNUSED(line); Q_UNUSED(line);
Q_UNUSED(context); Q_UNUSED(context);
Q_UNUSED(message); Q_UNUSED(message);
#if defined(QT_NO_DEBUG) Q_UNUSED(audit);
#if defined(QT_DEBUG)
# if defined(Q_CC_MSVC)
if (!audit || IsDebuggerPresent())
{
__debugbreak();
return;
}
# elif defined(BLACK_HAS_BUILTIN_DEBUGGER)
__builtin_debugger();
# elif defined(Q_PROCESSOR_X86)
__asm__ volatile("int $0x03");
# elif defined(Q_PROCESSOR_ARM)
__asm__ volatile(".inst 0xe7f001f0");
# elif defined(Q_OS_UNIX)
raise(SIGTRAP);
# else
Q_ASSERT(false);
# endif
#endif
#if defined(QT_NO_DEBUG) || defined(Q_CC_MSVC)
# if defined(BLACK_USE_CRASHPAD) # if defined(BLACK_USE_CRASHPAD)
CRASHPAD_SIMULATE_CRASH(); CRASHPAD_SIMULATE_CRASH();
# endif # endif
@@ -51,18 +72,6 @@ namespace BlackMisc
{ {
CLogMessage(CLogCategory::verification()).warning("Failed to verify: %1 in %2 line %3") << condition << filename << line; CLogMessage(CLogCategory::verification()).warning("Failed to verify: %1 in %2 line %3") << condition << filename << line;
} }
#elif defined(Q_CC_MSVC)
__debugbreak();
#elif defined(BLACK_HAS_BUILTIN_DEBUGGER)
__builtin_debugger();
#elif defined(Q_PROCESSOR_X86)
__asm__ volatile("int $0x03");
#elif defined(Q_PROCESSOR_ARM)
__asm__ volatile(".inst 0xe7f001f0");
#elif defined(Q_OS_UNIX)
raise(SIGTRAP);
#else
Q_ASSERT(false);
#endif #endif
} }
} }

View File

@@ -30,7 +30,7 @@ namespace BlackMisc
inline void noop() {} inline void noop() {}
//! \private Called by BLACK_VERIFY when the condition is false. //! \private Called by BLACK_VERIFY when the condition is false.
BLACKMISC_EXPORT BLACK_NO_INLINE void failedVerify(const char *condition, const char *filename, int line, const char *context = nullptr, const char *message = nullptr); BLACKMISC_EXPORT BLACK_NO_INLINE void failedVerify(const char *condition, const char *filename, int line, const char *context, const char *message, bool audit);
} }
} }
@@ -39,8 +39,18 @@ namespace BlackMisc
* In debug builds, triggers a debugger breakpoint. In release builds, generates a warning. * In debug builds, triggers a debugger breakpoint. In release builds, generates a warning.
*/ */
//! @{ //! @{
#define BLACK_VERIFY_X(COND, WHERE, WHAT) ((COND) ? BlackMisc::Private::noop() : BlackMisc::Private::failedVerify(#COND, __FILE__, __LINE__, WHERE, WHAT)) #define BLACK_VERIFY_X(COND, WHERE, WHAT) ((COND) ? BlackMisc::Private::noop() : BlackMisc::Private::failedVerify(#COND, __FILE__, __LINE__, WHERE, WHAT, false))
#define BLACK_VERIFY(COND) BLACK_VERIFY_X(COND, nullptr, nullptr) #define BLACK_VERIFY(COND) BLACK_VERIFY_X(COND, nullptr, nullptr)
//! @} //! @}
/*!
* A weaker kind of verify. Indicative of a serious but recoverable problem originating in an external data source.
* In debug builds under debugging, triggers a debugger breakpoint. Otherwise generates a warning.
* Not a substitute for proper validation. A failed audit in production is suggestive of insufficient validation.
*/
//! @{
#define BLACK_AUDIT_X(COND, WHERE, WHAT) ((COND) ? BlackMisc::Private::noop() : BlackMisc::Private::failedVerify(#COND, __FILE__, __LINE__, WHERE, WHAT, true))
#define BLACK_AUDIT(COND) BLACK_AUDIT_X(COND, nullptr, nullptr)
//! @}
#endif #endif