From 68897f04bd60624fb57d1bd5add4ca7aed1d5e50 Mon Sep 17 00:00:00 2001 From: Stefan Boberg Date: Fri, 17 Sep 2021 15:39:49 +0200 Subject: Added IsDebuggerPresent() query function to query whether a debugger is currently attached to the running process --- zencore/include/zencore/zencore.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'zencore/include') diff --git a/zencore/include/zencore/zencore.h b/zencore/include/zencore/zencore.h index da17e61e3..14f915e76 100644 --- a/zencore/include/zencore/zencore.h +++ b/zencore/include/zencore/zencore.h @@ -155,7 +155,7 @@ namespace zen { ZENCORE_API bool IsPointerToStack(const void* ptr); // Query if pointer is within the stack of the currently executing thread ZENCORE_API bool IsApplicationExitRequested(); ZENCORE_API void RequestApplicationExit(int ExitCode); - +ZENCORE_API bool IsDebuggerPresent(); ZENCORE_API void zencore_forcelinktests(); } -- cgit v1.2.3 From 0080e35ddb363dcac604cd77c1a07c98e4e75f4b Mon Sep 17 00:00:00 2001 From: Stefan Boberg Date: Fri, 17 Sep 2021 15:42:30 +0200 Subject: clang-format --- zencore/include/zencore/zencore.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'zencore/include') diff --git a/zencore/include/zencore/zencore.h b/zencore/include/zencore/zencore.h index 14f915e76..8011ab241 100644 --- a/zencore/include/zencore/zencore.h +++ b/zencore/include/zencore/zencore.h @@ -158,7 +158,7 @@ ZENCORE_API void RequestApplicationExit(int ExitCode); ZENCORE_API bool IsDebuggerPresent(); ZENCORE_API void zencore_forcelinktests(); -} +} // namespace zen ////////////////////////////////////////////////////////////////////////// -- cgit v1.2.3 From 025999f216f0fe99d0eacd1f7a9c6276b834bcb8 Mon Sep 17 00:00:00 2001 From: Stefan Boberg Date: Fri, 17 Sep 2021 19:04:26 +0200 Subject: Removed WindowsException from public headers --- zencore/include/zencore/except.h | 51 +++------------------------------------- 1 file changed, 3 insertions(+), 48 deletions(-) (limited to 'zencore/include') diff --git a/zencore/include/zencore/except.h b/zencore/include/zencore/except.h index 08330e4bc..3bffbd3bb 100644 --- a/zencore/include/zencore/except.h +++ b/zencore/include/zencore/except.h @@ -15,63 +15,18 @@ namespace zen { #if ZEN_PLATFORM_WINDOWS -class WindowsException : public std::exception -{ -public: - WindowsException(std::string_view Message) - { - m_hResult = HRESULT_FROM_WIN32(GetLastError()); - m_Message = Message; - } - - WindowsException(HRESULT hRes, std::string_view Message) - { - m_hResult = hRes; - m_Message = Message; - } - - WindowsException(HRESULT hRes, const char* Message, const char* Detail) - { - m_hResult = hRes; - - ExtendableStringBuilder<128> msg; - msg.Append(Message); - msg.Append(" (detail: '"); - msg.Append(Detail); - msg.Append("')"); - - m_Message = msg.c_str(); - } - - virtual const char* what() const override { return m_Message.c_str(); } - -private: - std::string m_Message; - HRESULT m_hResult; -}; - -ZENCORE_API void ThrowSystemException(HRESULT hRes, std::string_view Message); +ZENCORE_API void ThrowSystemException [[noreturn]] (HRESULT hRes, std::string_view Message); #endif // ZEN_PLATFORM_WINDOWS -ZENCORE_API void ThrowLastError(std::string_view Message); +ZENCORE_API void ThrowLastError [[noreturn]] (std::string_view Message); #if __cpp_lib_source_location -ZENCORE_API void ThrowLastError(std::string_view Message, const std::source_location& Location); +ZENCORE_API void ThrowLastError [[noreturn]] (std::string_view Message, const std::source_location& Location); #endif ZENCORE_API std::string GetLastErrorAsString(); ZENCORE_API std::string GetWindowsErrorAsString(uint32_t Win32ErrorCode); -inline void -ThrowSystemException(const char* Message) -{ -#if ZEN_PLATFORM_WINDOWS - throw WindowsException(Message); -#else - ThrowLastError(Message); -#endif -} - inline int32_t GetLastError() { -- cgit v1.2.3 From feb3e97f486e474f0c5775a4c407ef6db540df49 Mon Sep 17 00:00:00 2001 From: Stefan Boberg Date: Fri, 17 Sep 2021 19:09:10 +0200 Subject: Assert improvements --- zencore/include/zencore/zencore.h | 76 +++++++++++++++++++++++++++------------ 1 file changed, 54 insertions(+), 22 deletions(-) (limited to 'zencore/include') diff --git a/zencore/include/zencore/zencore.h b/zencore/include/zencore/zencore.h index 8011ab241..4f9dc6322 100644 --- a/zencore/include/zencore/zencore.h +++ b/zencore/include/zencore/zencore.h @@ -3,7 +3,7 @@ #pragma once #include -#include +#include #include ////////////////////////////////////////////////////////////////////////// @@ -90,37 +90,69 @@ // Assert // +#if ZEN_PLATFORM_WINDOWS +// Tells the compiler to put the decorated function in a certain section (aka. segment) of the executable. +# define ZEN_CODE_SECTION(Name) __declspec(code_seg(Name)) +# define ZEN_FORCENOINLINE __declspec(noinline) /* Force code to NOT be inline */ +#else +# define ZEN_CODE_SECTION(Name) +# define ZEN_FORCENOINLINE +#endif + +#if ZEN_ARCH_ARM64 +// On ARM we can't do this because the executable will require jumps larger +// than the branch instruction can handle. Clang will only generate +// the trampolines in the .text segment of the binary. If the uedbg segment +// is present it will generate code that it cannot link. +# define ZEN_DEBUG_SECTION +#else +// We'll put all assert implementation code into a separate section in the linked +// executable. This code should never execute so using a separate section keeps +// it well off the hot path and hopefully out of the instruction cache. It also +// facilitates reasoning about the makeup of a compiled/linked binary. +# define ZEN_DEBUG_SECTION ZEN_CODE_SECTION(".zcold") +#endif // DO_CHECK || DO_GUARD_SLOW + namespace zen { -class AssertException : public std::exception +class AssertException : public std::logic_error { public: - AssertException(const char* Msg); - ~AssertException(); - - [[nodiscard]] virtual char const* what() const noexcept override { return m_Msg.c_str(); } - -private: - std::string m_Msg; + AssertException(const char* Msg) : std::logic_error(Msg) {} }; } // namespace zen -#define ZEN_ASSERT(x, ...) \ - do \ - { \ - if (x) \ - break; \ - throw ::zen::AssertException{#x}; \ +template +RetType ZEN_FORCENOINLINE ZEN_DEBUG_SECTION +DispatchAssert(InnerType&& Inner, ArgTypes const&... Args) +{ + return Inner(Args...); +} + +#define ZEN_ASSERT(x, ...) \ + do \ + { \ + if (x) [[unlikely]] \ + break; \ + struct Impl \ + { \ + static void ZEN_FORCENOINLINE ZEN_DEBUG_SECTION ExecThrow [[noreturn]] () { throw ::zen::AssertException{#x}; } \ + }; \ + Impl::ExecThrow(); \ } while (false) #ifndef NDEBUG -# define ZEN_ASSERT_SLOW(x, ...) \ - do \ - { \ - if (x) \ - break; \ - throw ::zen::AssertException{#x}; \ +# define ZEN_ASSERT_SLOW(x, ...) \ + do \ + { \ + if (x) [[unlikely]] \ + break; \ + struct Impl \ + { \ + static void ZEN_FORCENOINLINE ZEN_DEBUG_SECTION ExecThrow [[noreturn]] () { throw ::zen::AssertException{#x}; } \ + }; \ + Impl::ExecThrow(); \ } while (false) #else # define ZEN_ASSERT_SLOW(x, ...) @@ -148,7 +180,7 @@ char (&ZenArrayCountHelper(const T (&)[N]))[N + 1]; #define ZEN_UNUSED(...) ((void)__VA_ARGS__) #define ZEN_NOT_IMPLEMENTED(...) ZEN_ASSERT(false, __VA_ARGS__) -#define ZENCORE_API // Placeholder to allow DLL configs in the future +#define ZENCORE_API // Placeholder to allow DLL configs in the future (maybe) namespace zen { -- cgit v1.2.3 From a6244f914633a4245fc71a987cb42fce0b7d8671 Mon Sep 17 00:00:00 2001 From: Stefan Boberg Date: Fri, 17 Sep 2021 23:07:45 +0200 Subject: Added ThrowSystemError() helper --- zencore/include/zencore/except.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'zencore/include') diff --git a/zencore/include/zencore/except.h b/zencore/include/zencore/except.h index 3bffbd3bb..5cfefb1e2 100644 --- a/zencore/include/zencore/except.h +++ b/zencore/include/zencore/except.h @@ -24,6 +24,8 @@ ZENCORE_API void ThrowLastError [[noreturn]] (std::string_view Message); ZENCORE_API void ThrowLastError [[noreturn]] (std::string_view Message, const std::source_location& Location); #endif +ZENCORE_API void ThrowSystemError [[noreturn]] (uint32_t ErrorCode, std::string_view Message); + ZENCORE_API std::string GetLastErrorAsString(); ZENCORE_API std::string GetWindowsErrorAsString(uint32_t Win32ErrorCode); -- cgit v1.2.3 From 91c305d98ab2a0482114c2d52d23ef787f08190d Mon Sep 17 00:00:00 2001 From: Stefan Boberg Date: Fri, 17 Sep 2021 23:16:34 +0200 Subject: Added IsInteractiveSession() query to help identify if the process is running as a daemon or as an interactive process --- zencore/include/zencore/zencore.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'zencore/include') diff --git a/zencore/include/zencore/zencore.h b/zencore/include/zencore/zencore.h index 4f9dc6322..310f6c4ed 100644 --- a/zencore/include/zencore/zencore.h +++ b/zencore/include/zencore/zencore.h @@ -188,6 +188,8 @@ ZENCORE_API bool IsPointerToStack(const void* ptr); // Query if pointer is with ZENCORE_API bool IsApplicationExitRequested(); ZENCORE_API void RequestApplicationExit(int ExitCode); ZENCORE_API bool IsDebuggerPresent(); +ZENCORE_API bool IsInteractiveSession(); + ZENCORE_API void zencore_forcelinktests(); } // namespace zen -- cgit v1.2.3 From f920793c7585a11c60346d306108f90368878d32 Mon Sep 17 00:00:00 2001 From: Stefan Boberg Date: Sun, 19 Sep 2021 18:36:50 +0200 Subject: Added testutils for use in writing tests Currently contains helpers for managing temporary directories used in tests --- zencore/include/zencore/testutils.h | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 zencore/include/zencore/testutils.h (limited to 'zencore/include') diff --git a/zencore/include/zencore/testutils.h b/zencore/include/zencore/testutils.h new file mode 100644 index 000000000..72d985d5c --- /dev/null +++ b/zencore/include/zencore/testutils.h @@ -0,0 +1,31 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include + +namespace zen { + +std::filesystem::path CreateTemporaryDirectory(); + +class ScopedTemporaryDirectory +{ +public: + ScopedTemporaryDirectory(); + ~ScopedTemporaryDirectory(); + + std::filesystem::path& Path() { return m_RootPath; } + +private: + std::filesystem::path m_RootPath; +}; + +struct ScopedCurrentDirectoryChange +{ + std::filesystem::path OldPath{std::filesystem::current_path()}; + + ScopedCurrentDirectoryChange() { std::filesystem::current_path(CreateTemporaryDirectory()); } + ~ScopedCurrentDirectoryChange() { std::filesystem::current_path(OldPath); } +}; + +} // namespace zen -- cgit v1.2.3 From ed9d27f5e7b2e8eda835e67af302f097e5932366 Mon Sep 17 00:00:00 2001 From: Stefan Boberg Date: Sun, 19 Sep 2021 18:38:31 +0200 Subject: Added GetSessionIdString() which returns a text representation of the session id --- zencore/include/zencore/session.h | 3 ++- zencore/include/zencore/uid.h | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'zencore/include') diff --git a/zencore/include/zencore/session.h b/zencore/include/zencore/session.h index 2da41b2c8..dd90197bf 100644 --- a/zencore/include/zencore/session.h +++ b/zencore/include/zencore/session.h @@ -8,6 +8,7 @@ namespace zen { struct Oid; -ZENCORE_API Oid GetSessionId(); +ZENCORE_API [[nodiscard]] Oid GetSessionId(); +ZENCORE_API [[nodiscard]] std::string_view GetSessionIdString(); } // namespace zen diff --git a/zencore/include/zencore/uid.h b/zencore/include/zencore/uid.h index f095c49ef..f4e9ab65a 100644 --- a/zencore/include/zencore/uid.h +++ b/zencore/include/zencore/uid.h @@ -60,6 +60,7 @@ struct Oid const Oid& Generate(); [[nodiscard]] static Oid FromHexString(const std::string_view String); StringBuilderBase& ToString(StringBuilderBase& OutString) const; + void ToString(char OutString[StringLength]); [[nodiscard]] static Oid FromMemory(const void* Ptr); auto operator<=>(const Oid& rhs) const = default; -- cgit v1.2.3 From c86315ea955408659eb7ea32798693975e27b9b7 Mon Sep 17 00:00:00 2001 From: Stefan Boberg Date: Sun, 19 Sep 2021 22:35:12 +0200 Subject: Changed so Windows also uses the portable std::mutex implementation and reworked some code which would not compile after the change --- zencore/include/zencore/thread.h | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'zencore/include') diff --git a/zencore/include/zencore/thread.h b/zencore/include/zencore/thread.h index e65867ec4..7889682cd 100644 --- a/zencore/include/zencore/thread.h +++ b/zencore/include/zencore/thread.h @@ -4,9 +4,7 @@ #include "zencore.h" -#if !ZEN_PLATFORM_WINDOWS -# include -#endif +#include #include @@ -66,11 +64,7 @@ public: }; private: -#if ZEN_PLATFORM_WINDOWS - void* m_Srw = nullptr; -#else std::shared_mutex m_Mutex; -#endif }; /** Basic abstraction of a simple event synchronization mechanism (aka 'binary semaphore') -- cgit v1.2.3