common: Implement assertion framework

This commit introduces the core assertion subsystem as defined in
`DESIGN_DOC_ASSERT_FRAMEWORK.md`.

Signed-off-by: Ronald Caesar <github43132@proton.me>
This commit is contained in:
Ronald Caesar 2025-09-21 09:42:05 -04:00
parent ba82ab5e9b
commit df86db1aa4
3 changed files with 72 additions and 0 deletions

View file

@ -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

44
src/common/passert.cpp Normal file
View file

@ -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();
}

27
src/common/passert.h Normal file
View file

@ -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