From fe4c4d077ac9d8401e8028c2d141bda4d2a7fe85 Mon Sep 17 00:00:00 2001 From: Hugo Date: Tue, 10 Feb 2026 23:46:06 +0100 Subject: [PATCH 1/2] feat(logger): add external coretrace-logger to runtime log --- CMakeLists.txt | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 748dca1..139522d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -44,6 +44,14 @@ set(LIB_SOURCES src/compilerlib/instrumentation/vtable.cpp ) +# ── coretrace-logger (external logging library) ── +include(FetchContent) +FetchContent_Declare(coretrace-logger + GIT_REPOSITORY https://github.com/CoreTrace/coretrace-log.git + GIT_TAG main +) +FetchContent_MakeAvailable(coretrace-logger) + add_library(ct_instrument_runtime STATIC src/runtime/ct_instrument_runtime.cpp src/runtime/ct_runtime_alloc.cpp @@ -56,6 +64,7 @@ add_library(ct_instrument_runtime STATIC src/runtime/ct_runtime_trace.cpp src/runtime/ct_runtime_vtable.cpp ) +target_link_libraries(ct_instrument_runtime PRIVATE coretrace_logger) set_target_properties(ct_instrument_runtime PROPERTIES OUTPUT_NAME "ct_instrument_runtime") if(ENABLE_DEBUG_ASAN) target_compile_options(ct_instrument_runtime PRIVATE -fno-sanitize=address) @@ -128,6 +137,7 @@ add_library(cc::compilerlib_static ALIAS compilerlib_static) target_compile_definitions(compilerlib_static PRIVATE CT_RUNTIME_LIB_PATH="$" + CT_RUNTIME_LOGGER_LIB_PATH="$" ) add_dependencies(compilerlib_static ct_instrument_runtime) @@ -182,6 +192,7 @@ add_library(cc::compilerlib_shared ALIAS compilerlib_shared) target_compile_definitions(compilerlib_shared PRIVATE CT_RUNTIME_LIB_PATH="$" + CT_RUNTIME_LOGGER_LIB_PATH="$" ) add_dependencies(compilerlib_shared ct_instrument_runtime) From 96d651dbd14c6d31a49e36a59ffd04cd33ec754c Mon Sep 17 00:00:00 2001 From: Hugo Date: Tue, 10 Feb 2026 23:48:47 +0100 Subject: [PATCH 2/2] feat(logger): add external coretrace-logger to runtime log --- src/compilerlib/compiler.cpp | 3 + src/runtime/ct_runtime_internal.h | 200 +++++++++--------- src/runtime/ct_runtime_logging.cpp | 327 +---------------------------- 3 files changed, 114 insertions(+), 416 deletions(-) diff --git a/src/compilerlib/compiler.cpp b/src/compilerlib/compiler.cpp index 926a6a1..a9b446c 100644 --- a/src/compilerlib/compiler.cpp +++ b/src/compilerlib/compiler.cpp @@ -295,6 +295,9 @@ namespace compilerlib ctx_.clang_args.push_back("-x"); ctx_.clang_args.push_back("none"); ctx_.clang_args.push_back(CT_RUNTIME_LIB_PATH); +#ifdef CT_RUNTIME_LOGGER_LIB_PATH + ctx_.clang_args.push_back(CT_RUNTIME_LOGGER_LIB_PATH); +#endif #ifdef __APPLE__ ctx_.clang_args.push_back("-lc++"); #else diff --git a/src/runtime/ct_runtime_internal.h b/src/runtime/ct_runtime_internal.h index 59da32b..a5c84b8 100644 --- a/src/runtime/ct_runtime_internal.h +++ b/src/runtime/ct_runtime_internal.h @@ -3,6 +3,8 @@ #include "compilerlib/attributes.hpp" +#include + #include #include #include @@ -13,62 +15,16 @@ #define CT_NOINSTR __attribute__((no_instrument_function)) -enum class CTColor -{ - Reset, - - Dim, - Bold, - Underline, - Italic, - Blink, - Reverse, - Hidden, - Strike, - - Black, - Red, - Green, - Yellow, - Blue, - Magenta, - Cyan, - White, - - Gray, - BrightRed, - BrightGreen, - BrightYellow, - BrightBlue, - BrightMagenta, - BrightCyan, - BrightWhite, - - BgBlack, - BgRed, - BgGreen, - BgYellow, - BgBlue, - BgMagenta, - BgCyan, - BgWhite, - - BgGray, - BgBrightRed, - BgBrightGreen, - BgBrightYellow, - BgBrightBlue, - BgBrightMagenta, - BgBrightCyan, - BgBrightWhite, -}; +// ############################################# +// Compatibility aliases: CTColor -> coretrace::Color +// ############################################# -enum class CTLevel -{ - Info = 0, - Warn = 1, - Error = 2 -}; +using CTColor = coretrace::Color; +using CTLevel = coretrace::Level; + +// ############################################# +// Entry states (runtime-specific, not in logger) +// ############################################# enum { @@ -79,6 +35,10 @@ enum CT_ENTRY_AUTOFREED = 4 }; +// ############################################# +// Runtime globals +// ############################################# + extern int ct_disable_trace; extern int ct_disable_alloc; extern int ct_disable_bounds; @@ -118,23 +78,13 @@ extern "C" CT_NODISCARD CT_NOINSTR int ct_early_trace_should_log(void); } +// ############################################# +// Runtime-specific functions (NOT in coretrace-logger) +// ############################################# + CT_NODISCARD CT_NOINSTR size_t ct_strlen(const char* str); CT_NODISCARD CT_NOINSTR int ct_streq(const char* lhs, const char* rhs); -CT_NODISCARD CT_NOINSTR std::string_view ct_color(CTColor color); -CT_NODISCARD CT_NOINSTR std::string_view ct_level_label(CTLevel level); -CT_NODISCARD CT_NOINSTR std::string_view ct_level_color(CTLevel level); -CT_NODISCARD CT_NOINSTR int ct_pid(void); -CT_NODISCARD CT_NOINSTR unsigned long long ct_thread_id(void); CT_NODISCARD CT_NOINSTR const char* ct_site_name(const char* site); -CT_NODISCARD CT_NOINSTR int ct_log_is_enabled(void); -CT_NOINSTR void ct_enable_logging(void); -CT_NOINSTR void ct_disable_logging(void); -CT_NOINSTR void ct_write_prefix(CTLevel level); -CT_NOINSTR void ct_write_raw(const char* data, size_t size); -CT_NOINSTR void ct_write_str(std::string_view str); -CT_NOINSTR void ct_write_cstr(const char* str); -CT_NOINSTR void ct_write_dec(size_t value); -CT_NOINSTR void ct_write_hex(uintptr_t value); CT_NOINSTR void ct_maybe_install_backtrace(void); CT_NOINSTR void ct_init_env_once(void); CT_NOINSTR void ct_lock_acquire(void); @@ -161,10 +111,94 @@ CT_NOINSTR void ct_report_bounds_error(const void* base, const void* ptr, size_t size_t alloc_size, const char* alloc_site, unsigned char state); +// ############################################# +// Compatibility wrappers: delegate to coretrace::* +// These allow existing runtime code to keep using +// the ct_* API without any changes. +// ############################################# + +CT_NODISCARD CT_NOINSTR inline std::string_view ct_color(CTColor color) +{ + return coretrace::color(color); +} + +CT_NODISCARD CT_NOINSTR inline std::string_view ct_level_label(CTLevel level) +{ + return coretrace::level_label(level); +} + +CT_NODISCARD CT_NOINSTR inline std::string_view ct_level_color(CTLevel level) +{ + return coretrace::level_color(level); +} + +CT_NODISCARD CT_NOINSTR inline int ct_pid(void) +{ + return coretrace::pid(); +} + +CT_NODISCARD CT_NOINSTR inline unsigned long long ct_thread_id(void) +{ + return coretrace::thread_id(); +} + +CT_NODISCARD CT_NOINSTR inline int ct_log_is_enabled(void) +{ + return coretrace::log_is_enabled() ? 1 : 0; +} + +CT_NOINSTR inline void ct_enable_logging(void) +{ + coretrace::enable_logging(); +} + +CT_NOINSTR inline void ct_disable_logging(void) +{ + coretrace::disable_logging(); +} + +CT_NOINSTR inline void ct_write_raw(const char* data, size_t size) +{ + coretrace::write_raw(data, size); +} + +CT_NOINSTR inline void ct_write_str(std::string_view str) +{ + coretrace::write_str(str); +} + +CT_NOINSTR inline void ct_write_cstr(const char* str) +{ + if (!str) + return; + coretrace::write_str(std::string_view(str)); +} + +CT_NOINSTR inline void ct_write_dec(size_t value) +{ + coretrace::write_dec(value); +} + +CT_NOINSTR inline void ct_write_hex(uintptr_t value) +{ + coretrace::write_hex(value); +} + +CT_NOINSTR inline void ct_write_prefix(CTLevel level) +{ + coretrace::write_prefix(level); +} + +// ############################################# +// ct_log: compatibility wrapper +// Delegates to coretrace::write_log_line for +// mutex-protected atomic output. +// ############################################# + template CT_NOINSTR inline void ct_log(CTLevel level, std::string_view fmt, Args&&... args) { - if (!ct_log_is_enabled()) + if (!coretrace::log_is_enabled()) { return; } @@ -176,34 +210,12 @@ CT_NOINSTR inline void ct_log(CTLevel level, std::string_view fmt, Args&&... arg return; } - std::string prefix; - prefix.reserve(64); - prefix.append(ct_color(CTColor::Dim)); - prefix.append("|"); - prefix.append(std::to_string(ct_pid())); - prefix.append("|"); - prefix.append(ct_color(CTColor::Reset)); - prefix.push_back(' '); - - prefix.append(ct_color(CTColor::Gray)); - prefix.append(ct_color(CTColor::Italic)); - prefix.append("==ct== "); - prefix.append(ct_color(CTColor::Reset)); - - prefix.append(ct_level_color(level)); - prefix.push_back('['); - prefix.append(ct_level_label(level)); - prefix.push_back(']'); - prefix.append(ct_color(CTColor::Reset)); - prefix.push_back(' '); - - ct_write_raw(prefix.data(), prefix.size()); - ct_write_raw(msg.data(), msg.size()); + coretrace::write_log_line(level, {}, msg, std::source_location::current()); } catch (...) { static const char fallback[] = "ct: log format error\n"; - ct_write_raw(fallback, ct_strlen(fallback)); + coretrace::write_raw(fallback, sizeof(fallback) - 1); } } diff --git a/src/runtime/ct_runtime_logging.cpp b/src/runtime/ct_runtime_logging.cpp index bd820ab..fe4ffdd 100644 --- a/src/runtime/ct_runtime_logging.cpp +++ b/src/runtime/ct_runtime_logging.cpp @@ -1,43 +1,10 @@ #include "ct_runtime_internal.h" -#include -#include -#if defined(__linux__) -#include -#endif - -namespace -{ - int ct_log_enabled = 0; - int ct_log_atexit_registered = 0; - - CT_NODISCARD CT_NOINSTR int ct_use_color(void) - { - static int cached = -1; - - if (cached != -1) - return cached; - - if (getenv("NO_COLOR") != nullptr) - { - cached = 0; - return cached; - } - - cached = isatty(2) ? 1 : 0; - return cached; - } - - CT_NOINSTR void ct_register_atexit(void) - { - int expected = 0; - if (__atomic_compare_exchange_n(&ct_log_atexit_registered, &expected, 1, false, - __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE)) - { - std::atexit(ct_disable_logging); - } - } -} // namespace +// ############################################# +// Runtime-specific string utilities +// These are NOT part of coretrace-logger because +// they are specific to the instrumentation runtime. +// ############################################# CT_NODISCARD CT_NOINSTR size_t ct_strlen(const char* str) { @@ -67,158 +34,6 @@ CT_NODISCARD CT_NOINSTR int ct_streq(const char* lhs, const char* rhs) return *lhs == *rhs; } -CT_NODISCARD CT_NOINSTR std::string_view ct_color(CTColor color) -{ - if (!ct_use_color()) - return {}; - - switch (color) - { - case CTColor::Reset: - return "\x1b[0m"; - - case CTColor::Dim: - return "\x1b[2m"; - case CTColor::Bold: - return "\x1b[1m"; - case CTColor::Underline: - return "\x1b[4m"; - case CTColor::Italic: - return "\x1b[3m"; - case CTColor::Blink: - return "\x1b[5m"; - case CTColor::Reverse: - return "\x1b[7m"; - case CTColor::Hidden: - return "\x1b[8m"; - case CTColor::Strike: - return "\x1b[9m"; - - case CTColor::Black: - return "\x1b[30m"; - case CTColor::Red: - return "\x1b[31m"; - case CTColor::Green: - return "\x1b[32m"; - case CTColor::Yellow: - return "\x1b[33m"; - case CTColor::Blue: - return "\x1b[34m"; - case CTColor::Magenta: - return "\x1b[35m"; - case CTColor::Cyan: - return "\x1b[36m"; - case CTColor::White: - return "\x1b[37m"; - - case CTColor::Gray: - return "\x1b[90m"; - case CTColor::BrightRed: - return "\x1b[91m"; - case CTColor::BrightGreen: - return "\x1b[92m"; - case CTColor::BrightYellow: - return "\x1b[93m"; - case CTColor::BrightBlue: - return "\x1b[94m"; - case CTColor::BrightMagenta: - return "\x1b[95m"; - case CTColor::BrightCyan: - return "\x1b[96m"; - case CTColor::BrightWhite: - return "\x1b[97m"; - - case CTColor::BgBlack: - return "\x1b[40m"; - case CTColor::BgRed: - return "\x1b[41m"; - case CTColor::BgGreen: - return "\x1b[42m"; - case CTColor::BgYellow: - return "\x1b[43m"; - case CTColor::BgBlue: - return "\x1b[44m"; - case CTColor::BgMagenta: - return "\x1b[45m"; - case CTColor::BgCyan: - return "\x1b[46m"; - case CTColor::BgWhite: - return "\x1b[47m"; - - case CTColor::BgGray: - return "\x1b[100m"; - case CTColor::BgBrightRed: - return "\x1b[101m"; - case CTColor::BgBrightGreen: - return "\x1b[102m"; - case CTColor::BgBrightYellow: - return "\x1b[103m"; - case CTColor::BgBrightBlue: - return "\x1b[104m"; - case CTColor::BgBrightMagenta: - return "\x1b[105m"; - case CTColor::BgBrightCyan: - return "\x1b[106m"; - case CTColor::BgBrightWhite: - return "\x1b[107m"; - } - - return {}; -} - -CT_NODISCARD CT_NOINSTR std::string_view ct_level_label(CTLevel level) -{ - switch (level) - { - case CTLevel::Info: - return "INFO"; - case CTLevel::Warn: - return "WARN"; - case CTLevel::Error: - return "ERROR"; - } - - return "INFO"; -} - -CT_NODISCARD CT_NOINSTR std::string_view ct_level_color(CTLevel level) -{ - switch (level) - { - case CTLevel::Info: - return ct_color(CTColor::Green); - case CTLevel::Warn: - return ct_color(CTColor::Yellow); - case CTLevel::Error: - return ct_color(CTColor::Red); - } - - return ct_color(CTColor::Cyan); -} - -CT_NODISCARD CT_NOINSTR int ct_pid(void) -{ - static int cached = 0; - - if (cached == 0) - cached = static_cast(getpid()); - - return cached; -} - -CT_NODISCARD CT_NOINSTR unsigned long long ct_thread_id(void) -{ -#if defined(__APPLE__) - uint64_t tid = 0; - (void)pthread_threadid_np(nullptr, &tid); - return static_cast(tid); -#elif defined(__linux__) - return static_cast(syscall(SYS_gettid)); -#else - return reinterpret_cast(pthread_self()); -#endif -} - CT_NODISCARD CT_NOINSTR const char* ct_site_name(const char* site) { if (site && site[0] != '\0') @@ -230,135 +45,3 @@ CT_NODISCARD CT_NOINSTR const char* ct_site_name(const char* site) } return ""; } - -CT_NODISCARD CT_NOINSTR int ct_log_is_enabled(void) -{ - return __atomic_load_n(&ct_log_enabled, __ATOMIC_ACQUIRE) != 0; -} - -CT_NOINSTR void ct_disable_logging(void) -{ - __atomic_store_n(&ct_log_enabled, 0, __ATOMIC_RELEASE); -} - -CT_NOINSTR void ct_enable_logging(void) -{ - __atomic_store_n(&ct_log_enabled, 1, __ATOMIC_RELEASE); - ct_register_atexit(); -} - -CT_NOINSTR void ct_write_raw(const char* data, size_t size) -{ - if (!data || size == 0) - return; - - while (size > 0) - { - ssize_t written = write(2, data, size); - if (written > 0) - { - data += static_cast(written); - size -= static_cast(written); - continue; - } - if (written < 0 && errno == EINTR) - continue; - break; - } -} - -CT_NOINSTR void ct_write_str(std::string_view value) -{ - if (value.empty()) - return; - ct_write_raw(value.data(), value.size()); -} - -CT_NOINSTR void ct_write_cstr(const char* value) -{ - if (!value) - return; - ct_write_raw(value, ct_strlen(value)); -} - -CT_NOINSTR void ct_write_dec(size_t value) -{ - char buf[32]; - size_t idx = 0; - - if (value == 0) - { - buf[idx++] = '0'; - } - else - { - while (value != 0 && idx < sizeof(buf)) - { - buf[idx++] = static_cast('0' + (value % 10)); - value /= 10; - } - } - - for (size_t i = 0; i < idx / 2; ++i) - { - char tmp = buf[i]; - buf[i] = buf[idx - 1 - i]; - buf[idx - 1 - i] = tmp; - } - - ct_write_raw(buf, idx); -} - -CT_NOINSTR void ct_write_hex(uintptr_t value) -{ - char buf[2 + sizeof(uintptr_t) * 2]; - size_t idx = 0; - - buf[idx++] = '0'; - buf[idx++] = 'x'; - - bool started = false; - for (int shift = static_cast(sizeof(uintptr_t) * 8 - 4); shift >= 0; shift -= 4) - { - unsigned int nibble = static_cast((value >> shift) & 0xF); - if (!started && nibble == 0 && shift != 0) - continue; - - started = true; - if (nibble < 10) - { - buf[idx++] = static_cast('0' + nibble); - } - else - { - buf[idx++] = static_cast('a' + (nibble - 10)); - } - } - - if (!started) - buf[idx++] = '0'; - - ct_write_raw(buf, idx); -} - -CT_NOINSTR void ct_write_prefix(CTLevel level) -{ - ct_write_str(ct_color(CTColor::Dim)); - ct_write_cstr("|"); - ct_write_dec(static_cast(ct_pid())); - ct_write_cstr("|"); - ct_write_str(ct_color(CTColor::Reset)); - ct_write_cstr(" "); - - ct_write_str(ct_color(CTColor::Gray)); - ct_write_str(ct_color(CTColor::Italic)); - ct_write_cstr("==ct== "); - ct_write_str(ct_color(CTColor::Reset)); - - ct_write_str(ct_level_color(level)); - ct_write_cstr("["); - ct_write_str(ct_level_label(level)); - ct_write_cstr("]"); - ct_write_str(ct_color(CTColor::Reset)); - ct_write_cstr(" "); -}