aboutsummaryrefslogtreecommitdiff
path: root/src/zencore/zencore.cpp
diff options
context:
space:
mode:
authorDan Engelbrecht <[email protected]>2024-05-03 15:09:35 +0200
committerGitHub Enterprise <[email protected]>2024-05-03 15:09:35 +0200
commit75b91b3f2eb21332a35255eae3c523ad2d2e9bc7 (patch)
treed0db8b85af12bff7acbfe8a8e091169e89307b8b /src/zencore/zencore.cpp
parent5.5.1 (diff)
downloadzen-75b91b3f2eb21332a35255eae3c523ad2d2e9bc7.tar.xz
zen-75b91b3f2eb21332a35255eae3c523ad2d2e9bc7.zip
assert improvements (#72)
- Improvement: Asserts gives an immediate ERROR log entry with callstack and reason - Improvement: Asserts flushes the log before sending error report to Sentry
Diffstat (limited to 'src/zencore/zencore.cpp')
-rw-r--r--src/zencore/zencore.cpp69
1 files changed, 61 insertions, 8 deletions
diff --git a/src/zencore/zencore.cpp b/src/zencore/zencore.cpp
index c4fcc89de..9c48b355b 100644
--- a/src/zencore/zencore.cpp
+++ b/src/zencore/zencore.cpp
@@ -87,8 +87,64 @@ AssertException::FullDescription() const noexcept
return what();
}
+AssertImpl::AssertImpl() : NextAssertImpl(nullptr)
+{
+ AssertImpl** WriteAssertPtr = &CurrentAssertImpl;
+ while (*WriteAssertPtr)
+ {
+ WriteAssertPtr = &(*WriteAssertPtr)->NextAssertImpl;
+ }
+ *WriteAssertPtr = this;
+}
+
+AssertImpl::~AssertImpl()
+{
+ AssertImpl** WriteAssertPtr = &CurrentAssertImpl;
+ while ((*WriteAssertPtr) != this)
+ {
+ ZEN_ASSERT((*WriteAssertPtr) != nullptr);
+ WriteAssertPtr = &(*WriteAssertPtr)->NextAssertImpl;
+ }
+ *WriteAssertPtr = NextAssertImpl;
+}
+
void
-AssertImpl::ThrowAssertException(const char* Filename, int LineNumber, const char* FunctionName, const char* Msg)
+AssertImpl::ExecAssert(const char* Filename, int LineNumber, const char* FunctionName, const char* Msg)
+{
+ void* Frames[8];
+ uint32_t FrameCount = GetCallstack(2, 8, Frames);
+
+ CallstackFrames* Callstack = CreateCallstack(FrameCount, Frames);
+
+ AssertImpl* AssertImpl = CurrentAssertImpl;
+ while (AssertImpl)
+ {
+ AssertImpl->OnAssert(Filename, LineNumber, FunctionName, Msg, Callstack);
+ AssertImpl = AssertImpl->NextAssertImpl;
+ }
+ ThrowAssertException(Filename, LineNumber, FunctionName, Msg, Callstack);
+}
+void
+AssertImpl::OnAssert(const char* Filename, int LineNumber, const char* FunctionName, const char* Msg, CallstackFrames* Callstack)
+{
+ ZEN_UNUSED(FunctionName);
+
+ fmt::basic_memory_buffer<char, 2048> Message;
+ auto Appender = fmt::appender(Message);
+ fmt::format_to(Appender, "{}({}): ZEN_ASSERT({})\n{}", Filename, LineNumber, Msg, CallstackToString(Callstack));
+ Message.push_back('\0');
+
+ // We use direct ZEN_LOG here instead of ZEN_ERROR as we don't care about *this* code location in the log
+ ZEN_LOG(Log(), zen::logging::level::Err, "{}", Message.data());
+ zen::logging::FlushLogging();
+}
+
+void
+AssertImpl::ThrowAssertException(const char* Filename,
+ int LineNumber,
+ const char* FunctionName,
+ const char* Msg,
+ CallstackFrames* Callstack)
{
ZEN_UNUSED(FunctionName);
fmt::basic_memory_buffer<char, 2048> Message;
@@ -96,9 +152,7 @@ AssertImpl::ThrowAssertException(const char* Filename, int LineNumber, const cha
fmt::format_to(Appender, "{}({}): {}", Filename, LineNumber, Msg);
Message.push_back('\0');
- void* Frames[8];
- uint32_t FrameCount = GetCallstack(3, 8, Frames);
- throw AssertException(Message.data(), CreateCallstack(FrameCount, Frames));
+ throw AssertException(Message.data(), Callstack);
}
void refcount_forcelink();
@@ -239,11 +293,10 @@ TEST_CASE("Assert.Custom")
{
struct MyAssertImpl : AssertImpl
{
- virtual void ZEN_FORCENOINLINE ZEN_DEBUG_SECTION OnAssert(const char* Filename,
- int LineNumber,
- const char* FunctionName,
- const char* Msg)
+ virtual void ZEN_FORCENOINLINE ZEN_DEBUG_SECTION
+ OnAssert(const char* Filename, int LineNumber, const char* FunctionName, const char* Msg, CallstackFrames* Callstack)
{
+ ZEN_UNUSED(Callstack);
AssertFileName = Filename;
Line = LineNumber;
FuncName = FunctionName;