diff options
| author | EPICGAMES\thierry.begin <[email protected]> | 2024-04-08 10:43:16 -0400 |
|---|---|---|
| committer | EPICGAMES\thierry.begin <[email protected]> | 2024-04-08 10:43:16 -0400 |
| commit | b35e1258a043cab06950b2453f434861d99b918a (patch) | |
| tree | 695737774fa08ebaa0e32a9f95cb0247c34b3dc3 /src/zencore/include | |
| parent | Add docker support (diff) | |
| parent | Merge pull request #41 from ue-foundation/zs/import-oplog-clean (diff) | |
| download | zen-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.h | 37 | ||||
| -rw-r--r-- | src/zencore/include/zencore/scopeguard.h | 6 | ||||
| -rw-r--r-- | src/zencore/include/zencore/zencore.h | 47 |
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 |