From 7eca190f2703cc45a5fc47ca2f7e87ceae5d3ccb Mon Sep 17 00:00:00 2001 From: linuxversion <1660477+SomeCrazyGuy@users.noreply.github.com> Date: Wed, 26 Jun 2024 02:03:16 -0400 Subject: [PATCH] Revert "move debug logging to a separate file, improve thread safety" This reverts commit f14962c38cc2e2487da8bd1d9d7b4592cdec1e8c. --- Starfield Console Replacer.vcxproj | 4 +- Starfield Console Replacer.vcxproj.filters | 4 +- src/console.cpp | 7 +- src/debug.cpp | 150 -------------------- src/debug.h | 29 ---- src/main.cpp | 152 +++++++++++++++++++-- src/main.h | 23 +++- 7 files changed, 169 insertions(+), 200 deletions(-) delete mode 100644 src/debug.cpp delete mode 100644 src/debug.h diff --git a/Starfield Console Replacer.vcxproj b/Starfield Console Replacer.vcxproj index 6736001..06d8c3e 100644 --- a/Starfield Console Replacer.vcxproj +++ b/Starfield Console Replacer.vcxproj @@ -112,8 +112,8 @@ copy /Y "$(OutDir)$(TargetName).dll" "$(OutDir)BetterConsole.asi" - + @@ -142,7 +142,7 @@ copy /Y "$(OutDir)$(TargetName).dll" "$(OutDir)BetterConsole.asi" - + diff --git a/Starfield Console Replacer.vcxproj.filters b/Starfield Console Replacer.vcxproj.filters index 4b29587..be0e835 100644 --- a/Starfield Console Replacer.vcxproj.filters +++ b/Starfield Console Replacer.vcxproj.filters @@ -89,7 +89,7 @@ Source Files - + Source Files @@ -175,7 +175,7 @@ Header Files - + Header Files diff --git a/src/console.cpp b/src/console.cpp index f74ee22..3e7f82a 100644 --- a/src/console.cpp +++ b/src/console.cpp @@ -170,14 +170,11 @@ static void SetGamePaused(bool paused) { } static uintptr_t starting_console_command(void* param_1, int* param_2) { - // 5 means the game is ready to run a command - const auto IsStartingCommand = *param_2 == 5; - const auto ret = OLD_StartingConsoleCommand(param_1, param_2); //TODO: should we register listeners for this event ? - if (IsStartingCommand) { + if (*param_2 == 5) { // 5 means the game is ready to run a command StartingCommandCompleted = true; } - return ret; + return OLD_StartingConsoleCommand(param_1, param_2); } static void draw_console_window(void* imgui_context) { diff --git a/src/debug.cpp b/src/debug.cpp deleted file mode 100644 index 02b475f..0000000 --- a/src/debug.cpp +++ /dev/null @@ -1,150 +0,0 @@ -#include "main.h" -#include "path_manager.h" - -#include - - -static uint64_t frame_counter = 0; - -// increment the frame counter -extern void DebugTickFrame() { - ++frame_counter; -} - -// return true every nth frame as determined by `modulus` -extern bool DebugEveryNFrames(unsigned modulus) { - return (frame_counter % modulus == 0); -} - - -#ifdef MODMENU_DEBUG -struct FilenameOnly { - const char* name; - uint32_t name_len; -}; -static FilenameOnly filename_only(const char* path) { - FilenameOnly ret{ path, 0 }; - - for (uint32_t i = 0; path[i]; ++i) { - if (path[i] == '/' || path[i] == '\\') { - ret.name = &path[i + 1]; - } - } - - for (uint32_t i = 0; ret.name[i]; ++i) { - ret.name_len = i; - if (ret.name[i] == '.') break; - } - - return ret; -} - - - -// this assert does not log to file or allocate memory -// its the emergency use only assert for when all else fails -[[noreturn]] static void msg_assert(const char* message) { - MessageBoxA(NULL, message, "BetterConsole SUPER_ASSERT", 0); - abort(); -} -#define SUPER_ASSERT(CONDITION) do{if(!(CONDITION))msg_assert(#CONDITION);}while(0) - - -#include -std::mutex logging_mutex; -static thread_local char format_buffer[4096]; -static constexpr auto buffer_size = sizeof(format_buffer); -static void write_log(const char* const str) noexcept { - static HANDLE debugfile = INVALID_HANDLE_VALUE; - static thread_local bool is_locked = false; - - // drop logs on recursive lock - if (is_locked) return; - - logging_mutex.lock(); - is_locked = true; - - if (debugfile == INVALID_HANDLE_VALUE) { - char path[MAX_PATH]; - PathInDllDir(path, sizeof(path), "BetterConsoleLog.txt"); - debugfile = CreateFileA(path, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); - SUPER_ASSERT(debugfile != INVALID_HANDLE_VALUE); - TRACE("Writing log to %s", path); - } - if (debugfile != INVALID_HANDLE_VALUE) { - WriteFile(debugfile, str, (DWORD)strnlen(str, 4096), NULL, NULL); - FlushFileBuffers(debugfile); - } - else { - MessageBoxA(NULL, "Could not write to 'BetterConsoleLog.txt'", "ASSERTION FAILURE", 0); - abort(); - } - - logging_mutex.unlock(); - is_locked = false; -} -extern void DebugImpl(const char* const filename, const char* const func, int line, const char* const fmt, ...) noexcept { - const auto fn = filename_only(filename); - auto bytes = snprintf(format_buffer, buffer_size, "%8X %4u %16.*s %32s %4d>", GetCurrentThreadId(), frame_counter, fn.name_len, fn.name, func, line); - ASSERT(bytes > 0); - ASSERT(bytes < buffer_size); - - va_list args; - va_start(args, fmt); - bytes += vsnprintf(&format_buffer[bytes], buffer_size - bytes, fmt, args); - va_end(args); - ASSERT(bytes > 0); - ASSERT(bytes < buffer_size); - - format_buffer[bytes++] = '\n'; - format_buffer[bytes] = '\0'; - ASSERT(bytes < buffer_size); - - write_log(format_buffer); -} - -[[noreturn]] extern void AssertImpl(const char* const filename, const char* const func, int line, const char* const text) noexcept { - const auto fn = filename_only(filename); - snprintf( - format_buffer, - buffer_size, - "In file '%.*s'\n" - "In function '%s'\n" - "On line '%d'\n" - "Message: '%s'", - fn.name_len, - fn.name, - func, - line, - text - ); - write_log("!!! ASSERTION FAILURE !!!\n"); - write_log(format_buffer); - MessageBoxA(NULL, format_buffer, "BetterConsole Crashed!", 0); - abort(); -} - -extern void TraceImpl(const char* const filename, const char* const func, int line, const char* const fmt, ...) noexcept { - static bool init = false; - static char tracebuff[2048]; - const auto fn = filename_only(filename); - const auto bytes = snprintf(tracebuff, sizeof(tracebuff), "[%08u]%8.*s:%s:%d> ", frame_counter, fn.name_len, fn.name, func, line); - ASSERT(bytes > 0 && "trace buffer too small ?"); - va_list args; - va_start(args, fmt); - const auto bytes2 = vsnprintf(tracebuff + bytes, sizeof(tracebuff) - bytes, fmt, args); - ASSERT(bytes2 > 0 && "trace buffer too small ?"); - tracebuff[bytes + bytes2] = '\r'; - tracebuff[bytes + bytes2 + 1] = '\n'; - tracebuff[bytes + bytes2 + 2] = '\0'; - va_end(args); - if (!init) { - AllocConsole(); - FILE* file = nullptr; - freopen_s(&file, "CONIN$", "rb", stdin); - freopen_s(&file, "CONOUT$", "wb", stdout); - freopen_s(&file, "CONOUT$", "wb", stderr); - } - fputs(tracebuff, stdout); -} -#endif \ No newline at end of file diff --git a/src/debug.h b/src/debug.h deleted file mode 100644 index e09d99a..0000000 --- a/src/debug.h +++ /dev/null @@ -1,29 +0,0 @@ -#include "main.h" - - -#ifndef MODMENU_DEBUG -#ifdef _DEBUG -#define MODMENU_DEBUG -#endif // _DEBUG -#endif // !MODMENU_DEBUG - -#ifdef MODMENU_DEBUG -extern void DebugImpl(const char* const filename, const char* const func, int line, const char* const fmt, ...) noexcept; -[[noreturn]] extern void AssertImpl(const char* const filename, const char* const func, int line, const char* const text) noexcept; -extern void TraceImpl(const char* const filename, const char* const func, int line, const char* const fmt, ...) noexcept; -#define DEBUG(...) do { DebugImpl(__FILE__, __func__, __LINE__, " " __VA_ARGS__); } while(0) -#define ASSERT(CONDITION) do { if (!(CONDITION)) { AssertImpl(__FILE__, __func__, __LINE__, " " #CONDITION); } } while(0) -#define TRACE(...) do { TraceImpl(__FILE__, __func__, __LINE__, " " __VA_ARGS__); } while(0) -#define IMGUI_DEBUG_PARANOID -#else -#define DEBUG(...) do { } while(0) -#define ASSERT(...) do { } while(0) -#defince TRACE(...) do {} while (0) -#endif // MODMENU_DEBUG - - -// increment the frame counter -extern void DebugTickFrame(); - -// return true every nth frame as determined by `modulus` -extern bool DebugEveryNFrames(unsigned modulus); \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 945f8db..396f58b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -45,9 +45,146 @@ static decltype(FAKE_ResizeBuffers)* OLD_ResizeBuffers = nullptr; static decltype(FAKE_Present)* OLD_Present = nullptr; static decltype(FAKE_Wndproc)* OLD_Wndproc = nullptr; + static HINSTANCE self_module_handle = nullptr; static bool should_show_ui = false; static bool betterapi_load_selftest = false; +static uint32_t frame_count_since_init = 0; + + +#define EveryNFrames(N) ((frame_count_since_init%(N))==0) + +#ifdef MODMENU_DEBUG +struct FilenameOnly { + const char* name; + uint32_t name_len; +}; +static FilenameOnly filename_only(const char* path) { + FilenameOnly ret{ path, 0 }; + + for (uint32_t i = 0; path[i]; ++i) { + if (path[i] == '/' || path[i] == '\\') { + ret.name = &path[i + 1]; + } + } + + for (uint32_t i = 0; ret.name[i]; ++i) { + ret.name_len = i; + if (ret.name[i] == '.') break; + } + + return ret; +} + + + +// this assert does not log to file or allocate memory +// its the emergency use only assert for when all else fails +[[noreturn]] static void msg_assert(const char* message) { + MessageBoxA(NULL, message, "BetterConsole SUPER_ASSERT", 0); + abort(); +} +#define SUPER_ASSERT(CONDITION) do{if(!(CONDITION))msg_assert(#CONDITION);}while(0) + + +#include +std::mutex logging_mutex; +static thread_local char format_buffer[4096]; +static constexpr auto buffer_size = sizeof(format_buffer); +static void write_log(const char* const str) noexcept { + static HANDLE debugfile = INVALID_HANDLE_VALUE; + static thread_local bool is_locked = false; + + // drop logs on recursive lock + if (is_locked) return; + + logging_mutex.lock(); + is_locked = true; + + if (debugfile == INVALID_HANDLE_VALUE) { + char path[MAX_PATH]; + PathInDllDir(path, sizeof(path), "BetterConsoleLog.txt"); + debugfile = CreateFileA(path, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + SUPER_ASSERT(debugfile != INVALID_HANDLE_VALUE); + TRACE("Writing log to %s", path); + } + if (debugfile != INVALID_HANDLE_VALUE) { + WriteFile(debugfile, str, (DWORD)strnlen(str, 4096), NULL, NULL); + FlushFileBuffers(debugfile); + } + else { + MessageBoxA(NULL, "Could not write to 'BetterConsoleLog.txt'", "ASSERTION FAILURE", 0); + abort(); + } + + logging_mutex.unlock(); + is_locked = false; +} +extern void DebugImpl(const char* const filename, const char* const func, int line, const char* const fmt, ...) noexcept { + const auto fn = filename_only(filename); + auto bytes = snprintf(format_buffer, buffer_size, "%6u | %16.*s | %32s | %4d>", frame_count_since_init, fn.name_len, fn.name, func, line); + ASSERT(bytes > 0); + ASSERT(bytes < buffer_size); + + va_list args; + va_start(args, fmt); + bytes += vsnprintf(&format_buffer[bytes], buffer_size - bytes, fmt, args); + va_end(args); + ASSERT(bytes > 0); + ASSERT(bytes < buffer_size); + + format_buffer[bytes++] = '\n'; + format_buffer[bytes] = '\0'; + ASSERT(bytes < buffer_size); + + write_log(format_buffer); +} + +[[noreturn]] extern void AssertImpl(const char* const filename, const char* const func, int line, const char* const text) noexcept { + const auto fn = filename_only(filename); + snprintf( + format_buffer, + buffer_size, + "In file '%.*s'\n" + "In function '%s'\n" + "On line '%d'\n" + "Message: '%s'", + fn.name_len, + fn.name, + func, + line, + text + ); + write_log("!!! ASSERTION FAILURE !!!\n"); + write_log(format_buffer); + MessageBoxA(NULL, format_buffer, "BetterConsole Crashed!", 0); + abort(); +} + +extern void TraceImpl(const char* const filename, const char* const func, int line, const char* const fmt, ...) noexcept { + static bool init = false; + static char tracebuff[2048]; + const auto fn = filename_only(filename); + const auto bytes = snprintf(tracebuff, sizeof(tracebuff), "[%08u]%8.*s:%s:%d> ", frame_count_since_init, fn.name_len, fn.name, func, line); + ASSERT(bytes > 0 && "trace buffer too small ?"); + va_list args; + va_start(args, fmt); + const auto bytes2 = vsnprintf(tracebuff + bytes, sizeof(tracebuff) - bytes, fmt, args); + ASSERT(bytes2 > 0 && "trace buffer too small ?"); + tracebuff[bytes + bytes2] = '\r'; + tracebuff[bytes + bytes2 + 1] = '\n'; + tracebuff[bytes + bytes2 + 2] = '\0'; + va_end(args); + if (!init) { + AllocConsole(); + FILE* file = nullptr; + freopen_s(&file, "CONIN$", "rb", stdin); + freopen_s(&file, "CONOUT$", "wb", stdout); + freopen_s(&file, "CONOUT$", "wb", stderr); + } + fputs(tracebuff, stdout); +} +#endif //this is where the api* that all clients use comes from @@ -432,25 +569,18 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE self, DWORD fdwReason, LPVOID) { } -// This can be called from a different thread than the Present() thread, -// so we need to juggle the should_show_ui flag to prevent a race condition -// where dx11 gets initialized again before resizebuffers completes static HRESULT FAKE_ResizeBuffers(IDXGISwapChain3* This, UINT BufferCount, UINT Width, UINT Height, DXGI_FORMAT NewFormat, UINT SwapChainFlags) { - const bool previously_shown = should_show_ui; if (should_show_ui) { - should_show_ui = false; DEBUG("Releasing DX11"); DX11_ReleaseIfInitialized(); } DEBUG("ResizeBuffers: %p, BufferCount: %u, Width: %u, Height: %u, NewFormat: %u", This, BufferCount, Width, Height, NewFormat); - const auto ret = OLD_ResizeBuffers(This, BufferCount, Width, Height, NewFormat, SwapChainFlags); - should_show_ui = previously_shown; - return ret; + return OLD_ResizeBuffers(This, BufferCount, Width, Height, NewFormat, SwapChainFlags); } static HRESULT FAKE_Present(IDXGISwapChain3* This, UINT SyncInterval, UINT PresentFlags) { - if (DebugEveryNFrames(1200)) { + if (EveryNFrames(1200)) { DEBUG("render heartbeat, showing ui: %s", (should_show_ui)? "true" : "false"); } @@ -497,7 +627,7 @@ static HRESULT FAKE_Present(IDXGISwapChain3* This, UINT SyncInterval, UINT Prese DEBUG("Swapchain::Present returned error: %u", ret); } --loop_check; - DebugTickFrame(); + ++frame_count_since_init; return ret; } @@ -506,7 +636,7 @@ static HRESULT FAKE_Present(IDXGISwapChain3* This, UINT SyncInterval, UINT Prese static LRESULT FAKE_Wndproc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { static HWND last_window_handle = nullptr; - if (DebugEveryNFrames(1200)) { + if (EveryNFrames(1200)) { DEBUG("input heartbeat"); } diff --git a/src/main.h b/src/main.h index c94a34b..daca07e 100644 --- a/src/main.h +++ b/src/main.h @@ -5,13 +5,34 @@ #define MODMENU_DEBUG +#ifndef MODMENU_DEBUG +#ifdef _DEBUG +#define MODMENU_DEBUG +#endif // _DEBUG +#endif // !MODMENU_DEBUG + +#ifdef MODMENU_DEBUG +extern void DebugImpl(const char* const filename, const char* const func, int line, const char* const fmt, ...) noexcept; +[[noreturn]] extern void AssertImpl (const char* const filename, const char* const func, int line, const char* const text) noexcept; +extern void TraceImpl(const char* const filename, const char* const func, int line, const char* const fmt, ...) noexcept; +#define DEBUG(...) do { DebugImpl(__FILE__, __func__, __LINE__, " " __VA_ARGS__); } while(0) +#define ASSERT(CONDITION) do { if (!(CONDITION)) { AssertImpl(__FILE__, __func__, __LINE__, " " #CONDITION); } } while(0) +#define TRACE(...) do { TraceImpl(__FILE__, __func__, __LINE__, " " __VA_ARGS__); } while(0) +#define IMGUI_DEBUG_PARANOID +#else +#define DEBUG(...) do { } while(0) +#define ASSERT(...) do { } while(0) +#defince TRACE(...) do { } while(0) +#endif // MODMENU_DEBUG + + #define WIN32_LEAN_AND_MEAN #define VC_EXTRA_LEAN #define BETTERAPI_ENABLE_SFSE_MINIMAL #include "../betterapi.h" -#include "debug.h" + #include "callback.h" #include "hook_api.h" #include "simpledraw.h"