From df86db1aa423f4ff79b0ff978c2c8e5e9e710e57 Mon Sep 17 00:00:00 2001 From: Ronald Caesar Date: Sun, 21 Sep 2025 09:42:05 -0400 Subject: [PATCH] common: Implement assertion framework This commit introduces the core assertion subsystem as defined in `DESIGN_DOC_ASSERT_FRAMEWORK.md`. Signed-off-by: Ronald Caesar --- src/common/CMakeLists.txt | 1 + src/common/passert.cpp | 44 +++++++++++++++++++++++++++++++++++++++ src/common/passert.h | 27 ++++++++++++++++++++++++ 3 files changed, 72 insertions(+) create mode 100644 src/common/passert.cpp create mode 100644 src/common/passert.h diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index c5db7b3..64c2f34 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -7,6 +7,7 @@ target_sources(common PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/StringUtil.cpp ${CMAKE_CURRENT_SOURCE_DIR}/Thread.cpp ${CMAKE_CURRENT_SOURCE_DIR}/logging.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/passert.cpp ${CMAKE_CURRENT_SOURCE_DIR}/Logging/Backend.cpp ${CMAKE_CURRENT_SOURCE_DIR}/Logging/Filter.cpp ${CMAKE_CURRENT_SOURCE_DIR}/Logging/TextFormatter.cpp diff --git a/src/common/passert.cpp b/src/common/passert.cpp new file mode 100644 index 0000000..f2a5ee0 --- /dev/null +++ b/src/common/passert.cpp @@ -0,0 +1,44 @@ +#include "passert.h" +#include "stdarg.h" +#include "stdio.h" +#include "stdlib.h" +#include "string.h" + +#define ASSERT_MESSAGE_BUFFER_SIZE 1024 + +void pound_internal_assert_fail(const char* file, int line, const char* func, const char* expr_str, + const char* user_msg, ...) +{ + char assert_format[] = + " \ + ================================================================================ \n \ + PVM ASSERTION FAILURE \n \ + ================================================================================ \n \ + File: %s \n \ + Line: %d \n \ + Function: %s \n \ + Expression: %s \n \ + Message: %s \n \ + ================================================================================ \n \ + Terminating program via abort(). Core dump expected. \n \ + "; + + char message_str[ASSERT_MESSAGE_BUFFER_SIZE] = {}; + if (nullptr == user_msg) + { + (void)strcpy(message_str, "n/a"); + } + else + { + va_list args; + va_start(args, user_msg); + (void)vsnprintf(message_str, ASSERT_MESSAGE_BUFFER_SIZE, user_msg, args); + va_end(args); + } + + char buffer[ASSERT_MESSAGE_BUFFER_SIZE] = {}; + (void)snprintf(buffer, ASSERT_MESSAGE_BUFFER_SIZE, assert_format, file, line, func, expr_str, message_str); + + (void)fprintf(stderr, "%s", buffer); + abort(); +} diff --git a/src/common/passert.h b/src/common/passert.h new file mode 100644 index 0000000..053bc47 --- /dev/null +++ b/src/common/passert.h @@ -0,0 +1,27 @@ +#ifndef POUND_COMMON_ASSERT_H +#define POUND_COMMON_ASSERT_H + +__attribute__((noreturn)) void pound_internal_assert_fail(const char* file, int line, const char* func, + const char* expr_str, const char* user_msg, ...); + +#define PVM_ASSERT(expression, ...) \ + do \ + { \ + if (!(expression)) \ + { \ + pound_internal_assert_fail(__FILE__, __LINE__, __func__, #expression, nullptr, ##__VA_ARGS__); \ + } \ + } while (0) + +#define PVM_ASSERT_MSG(expression, format, ...) \ + do \ + { \ + if (!(expression)) \ + { \ + pound_internal_assert_fail(__FILE__, __LINE__, __func__, #expression, format, ##__VA_ARGS__); \ + } \ + } while (0) + +#define PVM_UNREACHABLE(...) pound_internal_assert_fail(__FILE__, __LINE__, __func__, "PVM_UNREACHABLE()", "Unreachable code executed", ##__VA_ARGS__); + +#endif // POUND_COMMON_ASSERT_H