aboutsummaryrefslogtreecommitdiff
path: root/src/zencore/zencore.cpp
diff options
context:
space:
mode:
authorEPICGAMES\thierry.begin <[email protected]>2024-04-08 10:43:16 -0400
committerEPICGAMES\thierry.begin <[email protected]>2024-04-08 10:43:16 -0400
commitb35e1258a043cab06950b2453f434861d99b918a (patch)
tree695737774fa08ebaa0e32a9f95cb0247c34b3dc3 /src/zencore/zencore.cpp
parentAdd docker support (diff)
parentMerge pull request #41 from ue-foundation/zs/import-oplog-clean (diff)
downloadzen-tb/docker.tar.xz
zen-tb/docker.zip
Merge branch 'main' of https://github.ol.epicgames.net/ue-foundation/zen into tb/dockertb/docker
Diffstat (limited to 'src/zencore/zencore.cpp')
-rw-r--r--src/zencore/zencore.cpp111
1 files changed, 96 insertions, 15 deletions
diff --git a/src/zencore/zencore.cpp b/src/zencore/zencore.cpp
index c97f5e5ca..c4fcc89de 100644
--- a/src/zencore/zencore.cpp
+++ b/src/zencore/zencore.cpp
@@ -6,12 +6,9 @@
# include <zencore/windows.h>
#endif
-#if ZEN_PLATFORM_LINUX
-# include <pthread.h>
-#endif
-
#include <zencore/assertfmt.h>
#include <zencore/blake3.h>
+#include <zencore/callstack.h>
#include <zencore/compactbinary.h>
#include <zencore/compactbinarybuilder.h>
#include <zencore/compactbinarypackage.h>
@@ -55,10 +52,59 @@ ExecAssertFmt(const char* Filename, int LineNumber, const char* FunctionName, st
namespace zen {
+AssertException::AssertException(const AssertException& Rhs) noexcept : _Mybase(Rhs), _Callstack(CloneCallstack(Rhs._Callstack))
+{
+}
+
+AssertException::AssertException(AssertException&& Rhs) noexcept : _Mybase(Rhs), _Callstack(Rhs._Callstack)
+{
+ Rhs._Callstack = nullptr;
+}
+
+AssertException::~AssertException() noexcept
+{
+ FreeCallstack(_Callstack);
+}
+
+AssertException&
+AssertException::operator=(const AssertException& Rhs) noexcept
+{
+ _Mybase::operator=(Rhs);
+
+ CallstackFrames* Callstack = CloneCallstack(Rhs._Callstack);
+ std::swap(_Callstack, Callstack);
+ FreeCallstack(Callstack);
+ return *this;
+}
+
+std::string
+AssertException::FullDescription() const noexcept
+{
+ if (_Callstack)
+ {
+ return fmt::format("'{}'\n{}", what(), CallstackToString(_Callstack));
+ }
+ return what();
+}
+
+void
+AssertImpl::ThrowAssertException(const char* Filename, int LineNumber, const char* FunctionName, const char* Msg)
+{
+ ZEN_UNUSED(FunctionName);
+ fmt::basic_memory_buffer<char, 2048> Message;
+ auto Appender = fmt::appender(Message);
+ 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));
+}
+
void refcount_forcelink();
+AssertImpl* AssertImpl::CurrentAssertImpl = nullptr;
AssertImpl AssertImpl::DefaultAssertImpl;
-AssertImpl* AssertImpl::CurrentAssertImpl = &AssertImpl::DefaultAssertImpl;
//////////////////////////////////////////////////////////////////////////
@@ -138,6 +184,7 @@ void
zencore_forcelinktests()
{
zen::blake3_forcelink();
+ zen::callstack_forcelink();
zen::compositebuffer_forcelink();
zen::compress_forcelink();
zen::crypto_forcelink();
@@ -174,24 +221,24 @@ TEST_SUITE_BEGIN("core.assert");
TEST_CASE("Assert.Default")
{
- bool A = true;
- bool B = false;
- CHECK_THROWS_WITH(ZEN_ASSERT(A == B), "A == B");
+ bool A = true;
+ bool B = false;
+ std::string Expected = fmt::format("{}({}): {}", __FILE__, __LINE__ + 1, "A == B");
+ CHECK_THROWS_WITH(ZEN_ASSERT(A == B), Expected.c_str());
}
TEST_CASE("Assert.Format")
{
- bool A = true;
- bool B = false;
- CHECK_THROWS_WITH(ZEN_ASSERT_FORMAT(A == B, "{} == {}", A, B), "assert(A == B) failed: true == false");
+ bool A = true;
+ bool B = false;
+ std::string Expected = fmt::format("{}({}): {}", __FILE__, __LINE__ + 1, "assert(A == B) failed: true == false");
+ CHECK_THROWS_WITH(ZEN_ASSERT_FORMAT(A == B, "{} == {}", A, B), Expected.c_str());
}
TEST_CASE("Assert.Custom")
{
struct MyAssertImpl : AssertImpl
{
- ZEN_FORCENOINLINE ZEN_DEBUG_SECTION MyAssertImpl() : PrevAssertImpl(CurrentAssertImpl) { CurrentAssertImpl = this; }
- virtual ZEN_FORCENOINLINE ZEN_DEBUG_SECTION ~MyAssertImpl() { CurrentAssertImpl = PrevAssertImpl; }
virtual void ZEN_FORCENOINLINE ZEN_DEBUG_SECTION OnAssert(const char* Filename,
int LineNumber,
const char* FunctionName,
@@ -202,7 +249,7 @@ TEST_CASE("Assert.Custom")
FuncName = FunctionName;
Message = Msg;
}
- AssertImpl* PrevAssertImpl;
+ AssertImpl* PrevAssertImpl = nullptr;
const char* AssertFileName = nullptr;
int Line = -1;
@@ -213,13 +260,47 @@ TEST_CASE("Assert.Custom")
MyAssertImpl MyAssert;
bool A = true;
bool B = false;
- CHECK_THROWS_WITH(ZEN_ASSERT(A == B), "A == B");
+ CHECK_THROWS_WITH(ZEN_ASSERT(A == B), std::string(fmt::format("{}({}): {}", __FILE__, __LINE__, "A == B")).c_str());
CHECK(MyAssert.AssertFileName != nullptr);
CHECK(MyAssert.Line != -1);
CHECK(MyAssert.FuncName != nullptr);
CHECK(strcmp(MyAssert.Message, "A == B") == 0);
}
+TEST_CASE("Assert.Callstack")
+{
+ try
+ {
+ ZEN_ASSERT(false);
+ }
+ catch (const AssertException& Assert)
+ {
+ ZEN_INFO("Assert failed: {}", Assert.what());
+ CHECK(Assert._Callstack->FrameCount > 0);
+ CHECK(Assert._Callstack->Frames != nullptr);
+ ZEN_INFO("Callstack:\n{}", CallstackToString(Assert._Callstack));
+ }
+
+ WorkerThreadPool Pool(1);
+ auto Task = Pool.EnqueueTask(std::packaged_task<int()>{[] {
+ ZEN_ASSERT(false);
+ return 1;
+ }});
+
+ try
+ {
+ (void)Task.get();
+ CHECK(false);
+ }
+ catch (const AssertException& Assert)
+ {
+ ZEN_INFO("Assert in future: {}", Assert.what());
+ CHECK(Assert._Callstack->FrameCount > 0);
+ CHECK(Assert._Callstack->Frames != nullptr);
+ ZEN_INFO("Callstack:\n{}", CallstackToString(Assert._Callstack));
+ }
+}
+
TEST_SUITE_END();
#endif