feat(diagnostics): make the logging + crash infrastructure actually work (W7-2, W7-3, W7-4)
The Foundation tier — answers the original "make it easier to diagnose problems" ask. - W7-2 (keystone): the app-level Logger file sink was never initialized, so LOG/LOGF/ VERBOSE_LOGF went nowhere and dragonx-debug.log didn't exist on Linux/macOS at all. main() now calls Logger::init(<config>/dragonx-debug.log) on every platform. Fixed a latent deadlock this exposed: init() wrote its banner via write(), which re-locks the non-recursive mutex_ it already holds — now written directly. On Windows the raw stdout/stderr freopen moved to a separate dragonx-stdout.log so the two writers don't contend on one file. Added testLoggerFileSink (also a deadlock guard — it would hang if the fix regressed). - W7-3: no crash handler existed on Linux/macOS. Added an async-signal-safe sigaction handler (SIGSEGV/ABRT/BUS/FPE/ILL) that writes the signal id + a backtrace_symbols_fd backtrace to dragonx-crash.log, then re-raises the default disposition for a core dump — the POSIX counterpart of the Windows SEH filter. - W7-4: Logger::init now rotates the log to a single .1 backup past 10 MB, so a long or verbose session can't grow it unbounded. Build-clean; ctest 1/1. Remaining Foundation: the QoL bundle (mostly UI). See docs/wallet-hardening.md. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
#include "daemon/daemon_controller.h"
|
||||
#include "daemon/embedded_daemon.h"
|
||||
#include "util/connect_stall.h"
|
||||
#include "util/logger.h"
|
||||
#include "data/transaction_history_cache.h"
|
||||
#include "data/address_book.h"
|
||||
#include "data/wallet_index.h"
|
||||
@@ -2546,6 +2547,33 @@ void testConsoleSecretRedaction()
|
||||
EXPECT_EQ(RedactConsoleCommand("getwalletinfo"), std::string("getwalletinfo"));
|
||||
}
|
||||
|
||||
void testLoggerFileSink()
|
||||
{
|
||||
using dragonx::util::Logger;
|
||||
namespace fsn = std::filesystem;
|
||||
fsn::path logPath = fsn::temp_directory_path() / "od_logger_test.log";
|
||||
std::error_code ec;
|
||||
fsn::remove(logPath, ec);
|
||||
fsn::remove(logPath.string() + ".1", ec);
|
||||
|
||||
// W7-2: init() opens the file sink and must NOT deadlock — it writes the banner under the same
|
||||
// non-recursive lock it holds (this test would hang if that regressed).
|
||||
Logger& lg = Logger::instance();
|
||||
EXPECT_TRUE(lg.init(logPath.string()));
|
||||
lg.write("hello-w7-2-sink");
|
||||
EXPECT_TRUE(fsn::exists(logPath));
|
||||
|
||||
std::ifstream f(logPath.string());
|
||||
std::string all, line;
|
||||
while (std::getline(f, line)) all += line + "\n";
|
||||
f.close();
|
||||
EXPECT_TRUE(all.find("hello-w7-2-sink") != std::string::npos);
|
||||
EXPECT_TRUE(all.find("Logger initialized") != std::string::npos);
|
||||
|
||||
fsn::remove(logPath, ec);
|
||||
fsn::remove(logPath.string() + ".1", ec);
|
||||
}
|
||||
|
||||
void testConnectHasStalled()
|
||||
{
|
||||
using dragonx::util::connectHasStalled;
|
||||
@@ -6906,6 +6934,7 @@ int main()
|
||||
testIsLocalHost();
|
||||
testAllowsPlaintextRemote();
|
||||
testConsoleSecretRedaction();
|
||||
testLoggerFileSink();
|
||||
testDaemonLifecycleExecution();
|
||||
testDaemonLifecycleAdapters();
|
||||
testConsoleTextLayout();
|
||||
|
||||
Reference in New Issue
Block a user