From 8b8de92e51db4cc4c1727712c736dcba5f79d369 Mon Sep 17 00:00:00 2001 From: Stefan Boberg Date: Mon, 25 Nov 2024 09:56:23 +0100 Subject: Insights-compatible memory tracking (#214) This change introduces support for tracing of memory allocation activity. The code is ported from UE5, and Unreal Insights can be used to analyze the output. This is currently only fully supported on Windows, but will be extended to Mac/Linux in the near future. To activate full memory tracking, pass `--trace=memory` on the commandline alongside `--tracehost=` or `-tracefile=`. For more control over how much detail is traced you can instead pass some combination of `callstack`, `memtag`, `memalloc` instead. In practice, `--trace=memory` is an alias for `--trace=callstack,memtag,memalloc`). For convenience we also support `--trace=memory_light` which omits call stacks. This change also introduces multiple memory allocators, which may be selected via command-line option `--malloc=`: * `mimalloc` - mimalloc (default, same as before) * `rpmalloc` - rpmalloc is another high performance allocator for multithreaded applications which may be a better option than mimalloc (to be evaluated). Due to toolchain limitations this is currently only supported on Windows. * `stomp` - an allocator intended to be used during development/debugging to help track down memory issues such as use-after-free or out-of-bounds access. Currently only supported on Windows. * `ansi` - fallback to default system allocator --- src/zencore/logging.cpp | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'src/zencore/logging.cpp') diff --git a/src/zencore/logging.cpp b/src/zencore/logging.cpp index 1a0a91b3d..7bd500b3b 100644 --- a/src/zencore/logging.cpp +++ b/src/zencore/logging.cpp @@ -6,6 +6,8 @@ #include #include +#include + ZEN_THIRD_PARTY_INCLUDES_START #include #include @@ -66,6 +68,7 @@ static_assert(offsetof(spdlog::source_loc, funcname) == offsetof(SourceLocation, void EmitLogMessage(LoggerRef& Logger, int LogLevel, const std::string_view Message) { + UE_MEMSCOPE(ELLMTag::Logging); const spdlog::level::level_enum InLevel = (spdlog::level::level_enum)LogLevel; Logger.SpdLogger->log(InLevel, Message); if (IsErrorLevel(LogLevel)) @@ -80,6 +83,7 @@ EmitLogMessage(LoggerRef& Logger, int LogLevel, const std::string_view Message) void EmitLogMessage(LoggerRef& Logger, int LogLevel, std::string_view Format, fmt::format_args Args) { + UE_MEMSCOPE(ELLMTag::Logging); zen::logging::LoggingContext LogCtx; fmt::vformat_to(fmt::appender(LogCtx.MessageBuffer), Format, Args); zen::logging::EmitLogMessage(Logger, LogLevel, LogCtx.Message()); @@ -88,6 +92,7 @@ EmitLogMessage(LoggerRef& Logger, int LogLevel, std::string_view Format, fmt::fo void EmitLogMessage(LoggerRef& Logger, const SourceLocation& InLocation, int LogLevel, const std::string_view Message) { + UE_MEMSCOPE(ELLMTag::Logging); const spdlog::source_loc& Location = *reinterpret_cast(&InLocation); const spdlog::level::level_enum InLevel = (spdlog::level::level_enum)LogLevel; Logger.SpdLogger->log(Location, InLevel, Message); @@ -103,6 +108,7 @@ EmitLogMessage(LoggerRef& Logger, const SourceLocation& InLocation, int LogLevel void EmitLogMessage(LoggerRef& Logger, const SourceLocation& InLocation, int LogLevel, std::string_view Format, fmt::format_args Args) { + UE_MEMSCOPE(ELLMTag::Logging); zen::logging::LoggingContext LogCtx; fmt::vformat_to(fmt::appender(LogCtx.MessageBuffer), Format, Args); zen::logging::EmitLogMessage(Logger, InLocation, LogLevel, LogCtx.Message()); @@ -111,6 +117,7 @@ EmitLogMessage(LoggerRef& Logger, const SourceLocation& InLocation, int LogLevel void EmitConsoleLogMessage(int LogLevel, const std::string_view Message) { + UE_MEMSCOPE(ELLMTag::Logging); const spdlog::level::level_enum InLevel = (spdlog::level::level_enum)LogLevel; ConsoleLog().SpdLogger->log(InLevel, Message); } @@ -118,6 +125,7 @@ EmitConsoleLogMessage(int LogLevel, const std::string_view Message) void EmitConsoleLogMessage(int LogLevel, std::string_view Format, fmt::format_args Args) { + UE_MEMSCOPE(ELLMTag::Logging); zen::logging::LoggingContext LogCtx; fmt::vformat_to(fmt::appender(LogCtx.MessageBuffer), Format, Args); zen::logging::EmitConsoleLogMessage(LogLevel, LogCtx.Message()); @@ -192,6 +200,8 @@ std::string LogLevels[level::LogLevelCount]; void ConfigureLogLevels(level::LogLevel Level, std::string_view Loggers) { + UE_MEMSCOPE(ELLMTag::Logging); + RwLock::ExclusiveLockScope _(LogLevelsLock); LogLevels[Level] = Loggers; } @@ -199,6 +209,8 @@ ConfigureLogLevels(level::LogLevel Level, std::string_view Loggers) void RefreshLogLevels(level::LogLevel* DefaultLevel) { + UE_MEMSCOPE(ELLMTag::Logging); + spdlog::details::registry::log_levels Levels; { @@ -275,6 +287,8 @@ Default() void SetDefault(std::string_view NewDefaultLoggerId) { + UE_MEMSCOPE(ELLMTag::Logging); + auto NewDefaultLogger = spdlog::get(std::string(NewDefaultLoggerId)); ZEN_ASSERT(NewDefaultLogger); @@ -293,6 +307,8 @@ ErrorLog() void SetErrorLog(std::string_view NewErrorLoggerId) { + UE_MEMSCOPE(ELLMTag::Logging); + if (NewErrorLoggerId.empty()) { TheErrorLogger = {}; @@ -310,6 +326,8 @@ SetErrorLog(std::string_view NewErrorLoggerId) LoggerRef Get(std::string_view Name) { + UE_MEMSCOPE(ELLMTag::Logging); + std::shared_ptr Logger = spdlog::get(std::string(Name)); if (!Logger) @@ -339,6 +357,8 @@ SuppressConsoleLog() LoggerRef ConsoleLog() { + UE_MEMSCOPE(ELLMTag::Logging); + std::call_once(ConsoleInitFlag, [&] { if (!ConLogger) { @@ -355,6 +375,8 @@ ConsoleLog() void InitializeLogging() { + UE_MEMSCOPE(ELLMTag::Logging); + TheDefaultLogger = *spdlog::default_logger_raw(); } -- cgit v1.2.3