-
Notifications
You must be signed in to change notification settings - Fork 3
Crash Logging
Crash logging is separate from normal logme logging.
The regular logging path (LogmeI, LogmeE, LogmeC, stream-style macros, format-style macros, channels, backends, runtime control, rotation, retention, and asynchronous output) is designed for normal application code. It is also the right path for controlled fatal conditions where the process is still executing normally.
A signal handler or crash handler is different. The process may have been interrupted while it held a lock, while it was inside the allocator, while it was writing a file, or while it was already inside the logger. Calling the full logging pipeline from that context can deadlock or fail before the last diagnostic is written.
For that case logme provides a low-level crash logging path.
Open the crash file while the process is still healthy:
Logme::Instance->OpenCrashLog("crash.log");By default crash output goes to stderr. A process can change the default crash targets:
Logme::Instance->SetCrashOutputMask(
Logme::CRASH_OUTPUT_FILE | Logme::CRASH_OUTPUT_STDERR
);Supported targets are:
| Flag | Destination |
|---|---|
CRASH_OUTPUT_FILE |
The file opened by OpenCrashLog()
|
CRASH_OUTPUT_STDERR |
Standard error |
CRASH_OUTPUT_STDOUT |
Standard output |
CRASH_OUTPUT_CONSOLE |
Alias for CRASH_OUTPUT_STDERR
|
LogmeCrashToFile does not open a file during the crash. It writes only to a file that was already prepared with OpenCrashLog(). This is intentional. Opening files, creating directories, constructing paths, or attaching backends during a crash would turn the crash path back into normal logging.
Use LogmeCrash when simple C-style formatting is still acceptable:
LogmeCrash("fatal error: code=%d", code);
LogmeCrashToFile("fatal error: code=%d", code);
LogmeCrashToStderr("fatal error: code=%d", code);
LogmeCrashToStdout("fatal error: code=%d", code);LogmeCrash formats into a fixed internal buffer using C printf-style formatting and then writes the resulting bytes directly to the selected crash output. It does not use channels, backends, C++ streams, std::format, fmt, rotation, retention, output flags, or the async queue.
This path is still less strict than the raw path because formatting is performed. Use it for emergency situations where the process is not fully destroyed and simple formatting is useful.
Use LogmeCrashRaw for the strictest path:
LogmeCrashRaw("SIGABRT received\n");
LogmeCrashRawToFile("SIGABRT received\n");
LogmeCrashRawToStderr("SIGABRT received\n");
LogmeCrashRawToStdout("SIGABRT received\n");The raw macros are intended for string literals. The size is known at compile time, so the macro does not need strlen() and does not build a std::string.
Use raw crash logging for the most constrained contexts, such as a minimal POSIX signal handler.
The shortcut macros write to one target. The mask-based forms are available when a call site wants to select or combine targets explicitly:
LogmeCrashTo(Logme::CRASH_OUTPUT_FILE | Logme::CRASH_OUTPUT_STDERR,
"signal received: %d", signum);
LogmeCrashRawTo(Logme::CRASH_OUTPUT_FILE | Logme::CRASH_OUTPUT_STDERR,
"SIGABRT received\n");Prepare the file during startup:
Logme::Instance->OpenCrashLog("crash.log");Then keep the handler minimal:
static void HandleSigabrt(int)
{
LogmeCrashRawToStderr("SIGABRT received\n");
LogmeCrashRawToFile("SIGABRT received\n");
::signal(SIGABRT, SIG_DFL);
::abort();
}If the handler needs a signal number and the process state is still good enough for simple C formatting, use the formatted crash path:
static void HandleSignal(int signum)
{
LogmeCrashToStderr("signal received: %d", signum);
LogmeCrashToFile("signal received: %d", signum);
::signal(signum, SIG_DFL);
::abort();
}For the most damaged process states, prefer the raw literal form.
LogmeC, LogmeCheck, CHECK, and LOG(FATAL) are controlled fatal paths. They write through the normal logging pipeline. If a fatal handler is installed, logme calls FlushAll() before invoking it.
Crash logging is different. LogmeCrash and LogmeCrashRaw bypass the normal logging pipeline and write directly to prepared crash outputs.
Use this rule:
LogmeC // controlled fatal path through normal logging
LogmeCrash // emergency path with simple C formatting
LogmeCrashRaw // minimal literal emergency markerSee Fatal Handling for controlled critical records and fatal-handler policy.
Crash logging is an emergency best-effort mechanism, not a delivery guarantee. The process can still terminate before the operating system accepts the write. The disk can be full. stderr can be redirected to a broken pipe. The process can be corrupted beyond recovery.
The crash path intentionally does not support:
- channels
- backends
- runtime control
- output flags
- JSON/XML formatting
- C++ streams
-
std::formator fmt - rotation or retention
- async queues
- automatic file opening during the crash
Those features belong to the normal logging path. Crash logging exists so a process can still attempt to leave a small emergency marker when the normal path is too expensive or unsafe to call.
logme — flexible runtime logging system
Home · Getting Started · Architecture · Output · Backends · Configuration
GitHub: https://github.com/efmsoft/logme
- Home
- Getting Started
- Why logme?
- Core Concepts
- Logging Macros
- Fatal Handling
- Crash Logging
- glog Compatibility
- C API
- Choosing Logging Macros
- Function tracing
- Trace Points
- Override Scopes
- Advanced Features
- Collapse Logging
- Feature Map
- Overview
- Console Backend
- Debugger Backend
- File Backend
- File Rotation & Retention
- Buffer Backend
- Ring Buffer Backend
- SharedFile Backend
- Callback Backend
- Windows Event Log Backend
- Custom Backends
- Runtime Control
- Configuration
- Configuration JSON
- Control Server
- Environment Control
- Control Policies
- Trace Points
- Message Filtering