fix: use reentrant localtime_r/localtime_s off the worker thread

std::localtime shares a process-wide static tm; both sites are reachable from background threads (the RPC price-parse on the worker thread, and Logger::write from worker/monitor threads), so a concurrent localtime call could clobber the struct between the call and the read. Copy into a local std::tm via localtime_r / localtime_s, matching the codebase's existing convention (console_tab rpcTraceTimestamp, app_network, etc.). From the console-tab audit; benign (garbled/stale timestamp only), no crash or state impact.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-18 18:03:10 -05:00
parent 7d47c6e14e
commit 82d3178119
2 changed files with 18 additions and 3 deletions

View File

@@ -57,7 +57,15 @@ void Logger::write(const std::string& message)
now.time_since_epoch()) % 1000;
std::stringstream ss;
ss << std::put_time(std::localtime(&time), "%Y-%m-%d %H:%M:%S");
// Reachable from worker/monitor threads — std::localtime shares a process-wide static tm, so use the
// reentrant variant into a local tm (the logger's own mutex can't protect other localtime callers).
std::tm tmv{};
#ifdef _WIN32
localtime_s(&tmv, &time);
#else
localtime_r(&time, &tmv);
#endif
ss << std::put_time(&tmv, "%Y-%m-%d %H:%M:%S");
ss << '.' << std::setfill('0') << std::setw(3) << ms.count();
ss << " | " << message;