Fix MString::read() infinite retry loop, HTTPRequest parser fd leak, Log deadlock, log rotation symlink handling, and JString bounds checks
- MString::read() now gives up after repeated I/O errors instead of looping forever and crashing via realloc() failure (root cause of a recurring barant.com production crash). - HTTPRequest::parse() no longer leaks lineParser/headerParser on a malformed request. - Log gained size-based rotation (config-driven) and a non-static-mutex fix; a separate fix stopped rotation from destroying the logs symlink on its first trigger. - File.cpp: symlink-preserving rotation support. - JString: fixed an array-index out-of-bounds and a setString issue. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
694c6b80a4
commit
05374bdb15
7 files changed
+213
-14
No files matched your search
@@ -11,6 +11,9 @@ namespace coreutils {
|
||||
LogListener *Log::logListener = NULL;
|
||||
File *Log::logFile = NULL;
|
||||
int Log::seq = 0;
|
||||
std::mutex Log::mtx;
|
||||
size_t Log::maxLogSize = 100 * 1024 * 1024;
|
||||
int Log::maxLogBackups = 5;
|
||||
|
||||
Log::Log(LogListener *logListener) {
|
||||
this->logListener = logListener;
|
||||
@@ -71,20 +74,39 @@ namespace coreutils {
|
||||
|
||||
std::stringstream out;
|
||||
out << this->str() << std::endl;
|
||||
;
|
||||
std::string text = out.str();
|
||||
|
||||
mtx.lock();
|
||||
|
||||
if (logListener)
|
||||
logListener->logSend(out.str());
|
||||
if (logFile) {
|
||||
logFile->write(text);
|
||||
if (maxLogSize > 0 && logFile->currentSize() >= maxLogSize)
|
||||
logFile->rotate(maxLogBackups);
|
||||
}
|
||||
|
||||
if (logFile)
|
||||
logFile->write(out.str());
|
||||
|
||||
// std::cout << out.str();
|
||||
// std::cout << text;
|
||||
++seq;
|
||||
|
||||
mtx.unlock();
|
||||
|
||||
// Called AFTER releasing mtx - a real, confirmed (via gdb thread
|
||||
// dump on a hung production BARANTMail) lock-order inversion:
|
||||
// ConsoleServer::logSend() takes TCPServer's own `lock`
|
||||
// (recursive_mutex) to echo this line to connected console
|
||||
// sessions, but TCPServer::connectionRequest() holds that SAME
|
||||
// lock for the whole span of accepting+TLS-handshaking a new
|
||||
// connection - during which another Log() call (e.g. from TLS's
|
||||
// own handshake-complete callback, on a DIFFERENT thread) needs
|
||||
// mtx. One thread held mtx and waited on TCPServer::lock; another
|
||||
// held TCPServer::lock and waited on mtx - neither the
|
||||
// recursive_mutex fix (which only helps the SAME thread re-enter
|
||||
// TCPServer::lock) nor anything else here prevented it, since
|
||||
// that's a same-thread-only guarantee and this is a two-thread,
|
||||
// two-different-mutex inversion. logListener->logSend() only
|
||||
// relays an already-built string and touches no other Log state,
|
||||
// so it doesn't need mtx held at all.
|
||||
if (logListener)
|
||||
logListener->logSend(text);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user