diff options
| author | Dan Engelbrecht <[email protected]> | 2024-05-03 15:09:35 +0200 |
|---|---|---|
| committer | GitHub Enterprise <[email protected]> | 2024-05-03 15:09:35 +0200 |
| commit | 75b91b3f2eb21332a35255eae3c523ad2d2e9bc7 (patch) | |
| tree | d0db8b85af12bff7acbfe8a8e091169e89307b8b /src/zencore/zencore.cpp | |
| parent | 5.5.1 (diff) | |
| download | zen-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.cpp | 69 |
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; |