aboutsummaryrefslogtreecommitdiff
path: root/src/zencore/include
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/include
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/include')
-rw-r--r--src/zencore/include/zencore/callstack.h37
-rw-r--r--src/zencore/include/zencore/scopeguard.h6
-rw-r--r--src/zencore/include/zencore/zencore.h47
3 files changed, 80 insertions, 10 deletions
diff --git a/src/zencore/include/zencore/callstack.h b/src/zencore/include/zencore/callstack.h
new file mode 100644
index 000000000..02ba8b3c3
--- /dev/null
+++ b/src/zencore/include/zencore/callstack.h
@@ -0,0 +1,37 @@
+// Copyright Epic Games, Inc. All Rights Reserved.
+
+#pragma once
+
+#include <zencore/zencore.h>
+
+#include <zencore/string.h>
+
+#include <string>
+#include <vector>
+
+namespace zen {
+
+struct CallstackFrames
+{
+ uint32_t FrameCount;
+ void** Frames;
+};
+
+CallstackFrames* CreateCallstack(uint32_t FrameCount, void** Frames) noexcept;
+CallstackFrames* CloneCallstack(const CallstackFrames* Callstack) noexcept;
+void FreeCallstack(CallstackFrames* Callstack) noexcept;
+
+uint32_t GetCallstack(int FramesToSkip, int FramesToCapture, void* OutAddresses[]);
+std::vector<std::string> GetFrameSymbols(uint32_t FrameCount, void** Frames);
+inline std::vector<std::string>
+GetFrameSymbols(const CallstackFrames* Callstack)
+{
+ return GetFrameSymbols(Callstack ? Callstack->FrameCount : 0, Callstack ? Callstack->Frames : nullptr);
+}
+
+void FormatCallstack(const CallstackFrames* Callstack, StringBuilderBase& SB);
+std::string CallstackToString(const CallstackFrames* Callstack);
+
+void callstack_forcelink(); // internal
+
+} // namespace zen
diff --git a/src/zencore/include/zencore/scopeguard.h b/src/zencore/include/zencore/scopeguard.h
index d04c8ed9c..3fd0564f6 100644
--- a/src/zencore/include/zencore/scopeguard.h
+++ b/src/zencore/include/zencore/scopeguard.h
@@ -21,7 +21,11 @@ public:
{
m_guardFunc();
}
- catch (std::exception& Ex)
+ catch (const AssertException& Ex)
+ {
+ ZEN_ERROR("Assert exception in scope guard: {}", Ex.FullDescription());
+ }
+ catch (const std::exception& Ex)
{
ZEN_ERROR("scope guard threw exception: '{}'", Ex.what());
}
diff --git a/src/zencore/include/zencore/zencore.h b/src/zencore/include/zencore/zencore.h
index 1a9060e29..cd1a34c7b 100644
--- a/src/zencore/include/zencore/zencore.h
+++ b/src/zencore/include/zencore/zencore.h
@@ -24,34 +24,63 @@
#endif
namespace zen {
+
+struct CallstackFrames;
+
class AssertException : public std::logic_error
{
public:
- inline explicit AssertException(const char* Msg) : std::logic_error(Msg) {}
+ using _Mybase = std::logic_error;
+
+ virtual ~AssertException() noexcept;
+
+ inline AssertException(const char* Msg, struct CallstackFrames* Callstack) noexcept : _Mybase(Msg), _Callstack(Callstack) {}
+
+ AssertException(const AssertException& Rhs) noexcept;
+
+ AssertException(AssertException&& Rhs) noexcept;
+
+ AssertException& operator=(const AssertException& Rhs) noexcept;
+
+ std::string FullDescription() const noexcept;
+
+ struct CallstackFrames* _Callstack = nullptr;
};
struct AssertImpl
{
+ ZEN_FORCENOINLINE ZEN_DEBUG_SECTION AssertImpl() : PrevAssertImpl(CurrentAssertImpl) { CurrentAssertImpl = this; }
+ virtual ZEN_FORCENOINLINE ZEN_DEBUG_SECTION ~AssertImpl() { CurrentAssertImpl = PrevAssertImpl; }
+
static void ZEN_FORCENOINLINE ZEN_DEBUG_SECTION ExecAssert
[[noreturn]] (const char* Filename, int LineNumber, const char* FunctionName, const char* Msg)
{
- CurrentAssertImpl->OnAssert(Filename, LineNumber, FunctionName, Msg);
- throw AssertException{Msg};
+ AssertImpl* AssertImpl = CurrentAssertImpl;
+ while (AssertImpl)
+ {
+ AssertImpl->OnAssert(Filename, LineNumber, FunctionName, Msg);
+ AssertImpl = AssertImpl->PrevAssertImpl;
+ }
+ ThrowAssertException(Filename, LineNumber, FunctionName, Msg);
}
-protected:
virtual void ZEN_FORCENOINLINE ZEN_DEBUG_SECTION OnAssert(const char* Filename,
int LineNumber,
const char* FunctionName,
const char* Msg)
{
- (void(Filename));
- (void(LineNumber));
- (void(FunctionName));
- (void(Msg));
+ ZEN_UNUSED(Filename);
+ ZEN_UNUSED(LineNumber);
+ ZEN_UNUSED(FunctionName);
+ ZEN_UNUSED(Msg);
}
- static AssertImpl DefaultAssertImpl;
+
+protected:
+ static void ZEN_FORCENOINLINE ZEN_DEBUG_SECTION ThrowAssertException
+ [[noreturn]] (const char* Filename, int LineNumber, const char* FunctionName, const char* Msg);
static AssertImpl* CurrentAssertImpl;
+ static AssertImpl DefaultAssertImpl;
+ AssertImpl* PrevAssertImpl = nullptr;
};
} // namespace zen