mirror of
https://github.com/KjellKod/g3log.git
synced 2024-12-12 10:23:50 +01:00
parent
d70ae50ee3
commit
bba825815a
BIN
docs/.DS_Store
vendored
Normal file
BIN
docs/.DS_Store
vendored
Normal file
Binary file not shown.
@ -148,45 +148,48 @@ namespace g3 {
|
||||
message.get()->setExpression(boolean_expression);
|
||||
|
||||
if (internal::wasFatal(level)) {
|
||||
auto fatalhook = g_fatal_pre_logging_hook;
|
||||
// In case the fatal_pre logging actually will cause a crash in its turn
|
||||
// let's not do recursive crashing!
|
||||
setFatalPreLoggingHook(g_pre_fatal_hook_that_does_nothing);
|
||||
++g_fatal_hook_recursive_counter; // thread safe counter
|
||||
// "benign" race here. If two threads crashes, with recursive crashes
|
||||
// then it's possible that the "other" fatal stack trace will be shown
|
||||
// that's OK since it was anyhow the first crash detected
|
||||
static const std::string first_stack_trace = stack_trace;
|
||||
fatalhook();
|
||||
message.get()->write().append(stack_trace);
|
||||
|
||||
if (g_fatal_hook_recursive_counter.load() > 1) {
|
||||
message.get()->write().append(
|
||||
"\n\n\nWARNING\n"
|
||||
"A recursive crash detected. It is likely the hook set with 'setFatalPreLoggingHook(...)' is responsible\n\n")
|
||||
.append("---First crash stacktrace: ")
|
||||
.append(first_stack_trace)
|
||||
.append("\n---End of first stacktrace\n");
|
||||
}
|
||||
FatalMessagePtr fatal_message{std::make_unique<FatalMessage>(*(message._move_only.get()), fatal_signal)};
|
||||
// At destruction, flushes fatal message to g3LogWorker
|
||||
// either we will stay here until the background worker has received the fatal
|
||||
// message, flushed the crash message to the sinks and exits with the same fatal signal
|
||||
//..... OR it's in unit-test mode then we throw a std::runtime_error (and never hit sleep)
|
||||
fatalCall(fatal_message);
|
||||
saveFatalMessage(level, stack_trace, message, fatal_signal);
|
||||
} else {
|
||||
pushMessageToLogger(message);
|
||||
}
|
||||
}
|
||||
|
||||
void saveFatalMessage(const LEVELS& level, const char* stack_trace, g3::LogMessagePtr& message, int& fatal_signal) {
|
||||
auto fatalhook = g_fatal_pre_logging_hook;
|
||||
// In case the fatal_pre logging actually will cause a crash in its turn
|
||||
// let's not do recursive crashing!
|
||||
setFatalPreLoggingHook(g_pre_fatal_hook_that_does_nothing);
|
||||
++g_fatal_hook_recursive_counter; // thread safe counter
|
||||
// "benign" race here. If two threads crashes, with recursive crashes
|
||||
// then it's possible that the "other" fatal stack trace will be shown
|
||||
// that's OK since it was anyhow the first crash detected
|
||||
static const std::string first_stack_trace = stack_trace;
|
||||
fatalhook();
|
||||
message.get()->write().append(stack_trace);
|
||||
|
||||
if (g_fatal_hook_recursive_counter.load() > 1) {
|
||||
message.get()->write().append(
|
||||
"\n\n\nWARNING\n"
|
||||
"A recursive crash detected. It is likely the hook set with 'setFatalPreLoggingHook(...)' is responsible\n\n")
|
||||
.append("---First crash stacktrace: ")
|
||||
.append(first_stack_trace)
|
||||
.append("\n---End of first stacktrace\n");
|
||||
}
|
||||
FatalMessagePtr fatal_message{std::make_unique<FatalMessage>(*(message._move_only.get()), fatal_signal)};
|
||||
// At destruction, flushes fatal message to g3LogWorker
|
||||
// either we will stay here until the background worker has received the fatal
|
||||
// message, flushed the crash message to the sinks and exits with the same fatal signal
|
||||
//..... OR it's in unit-test mode then we throw a std::runtime_error (and never hit sleep)
|
||||
fatalCall(fatal_message);
|
||||
}
|
||||
/**
|
||||
* save the message to the logger. In case of called before the logger is instantiated
|
||||
* the first message will be saved. Any following subsequent uninitialized log calls
|
||||
* will be ignored.
|
||||
*
|
||||
* The first initialized log entry will also save the first uninitialized log message, if any
|
||||
* @param log_entry to save to logger
|
||||
*/
|
||||
* save the message to the logger. In case of called before the logger is instantiated
|
||||
* the first message will be saved. Any following subsequent uninitialized log calls
|
||||
* will be ignored.
|
||||
*
|
||||
* The first initialized log entry will also save the first uninitialized log message, if any
|
||||
* @param log_entry to save to logger
|
||||
*/
|
||||
void pushMessageToLogger(LogMessagePtr incoming) { // todo rename to Push SavedMessage To Worker
|
||||
// Uninitialized messages are ignored but does not CHECK/crash the logger
|
||||
if (!internal::isLoggingInitialized()) {
|
||||
@ -196,9 +199,8 @@ namespace g3 {
|
||||
err.append(g_first_uninitialized_msg->message());
|
||||
std::string& str = g_first_uninitialized_msg->write();
|
||||
str.clear();
|
||||
str.append(err); // replace content
|
||||
std::cerr << str << std::endl;
|
||||
});
|
||||
str.append(err); // replace content
|
||||
std::cerr << str << std::endl; });
|
||||
return;
|
||||
}
|
||||
|
||||
@ -207,10 +209,10 @@ namespace g3 {
|
||||
}
|
||||
|
||||
/** Fatal call saved to logger. This will trigger SIGABRT or other fatal signal
|
||||
* to exit the program. After saving the fatal message the calling thread
|
||||
* will sleep forever (i.e. until the background thread catches up, saves the fatal
|
||||
* message and kills the software with the fatal signal.
|
||||
*/
|
||||
* to exit the program. After saving the fatal message the calling thread
|
||||
* will sleep forever (i.e. until the background thread catches up, saves the fatal
|
||||
* message and kills the software with the fatal signal.
|
||||
*/
|
||||
void pushFatalMessageToLogger(FatalMessagePtr message) {
|
||||
if (!isLoggingInitialized()) {
|
||||
std::ostringstream error;
|
||||
@ -228,10 +230,10 @@ namespace g3 {
|
||||
}
|
||||
|
||||
/** The default, initial, handling to send a 'fatal' event to g3logworker
|
||||
* the caller will stay here, eternally, until the software is aborted
|
||||
* ... in the case of unit testing it is the given "Mock" fatalCall that will
|
||||
* define the behaviour.
|
||||
*/
|
||||
* the caller will stay here, eternally, until the software is aborted
|
||||
* ... in the case of unit testing it is the given "Mock" fatalCall that will
|
||||
* define the behaviour.
|
||||
*/
|
||||
void fatalCall(FatalMessagePtr message) {
|
||||
g_fatal_to_g3logworker_function_ptr(FatalMessagePtr{std::move(message)});
|
||||
}
|
||||
|
@ -106,6 +106,8 @@ namespace g3 {
|
||||
void saveMessage(const char* message, const char* file, int line, const char* function, const LEVELS& level,
|
||||
const char* boolean_expression, int fatal_signal, const char* stack_trace);
|
||||
|
||||
void saveFatalMessage(const LEVELS& level, const char* stack_trace, g3::LogMessagePtr& message, int& fatal_signal);
|
||||
|
||||
// forwards the message to all sinks
|
||||
void pushMessageToLogger(LogMessagePtr log_entry);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user