Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide way to gracefully terminate or use spdlog in signal handlers #1607

Open
TamasFlorin opened this issue Jul 7, 2020 · 6 comments
Open

Comments

@TamasFlorin
Copy link
Contributor

Hey,

First of all, thank your for all the work that you have put into this!

I was wondering what is the right way of handling the following situation: we are using the async logger and the process suddenly crashes without having the chance to flush the log messages to the file.

My first thought was to install a signal handler for SIGSEGV and SIGABRT and call spdlog::shutdown() from the respective handler. However, the shutdown method does not seem to be async-safe since it uses std::mutex, meaning that this could cause deadlocks when the process crashes and that might be even worse than losing a few logs.

Are there any other suggestions that could help us get around this issue?

Thanks

@tt4g
Copy link
Contributor

tt4g commented Jul 7, 2020

There are not many safe operations within the signal handler (see reference: std::signal - cppreference.com).
And spdlog does not support its use within signal handlers.

One workaround is to use std::condition_variable to call a function that is not signal safe outside the signal function.
Like this link example code, if you call the notification function of std::condition_variable in the signal function and call spdlog::shutdown() when the process thread receives the notification,
spdlog will now shutdown when a signal is received.

@gabime
Copy link
Owner

gabime commented Jul 7, 2020

First of all, thank your for all the work that you have put into this!

Thanks for the feedback :)

I will add it to the todo list to implement in spdlog somehow (probably similar to @tt4g suggestion).

@gabime gabime changed the title async logger handle unexpected termination Provide way to graceful terminate or use spdlog in signal handlers Jul 7, 2020
@gabime gabime changed the title Provide way to graceful terminate or use spdlog in signal handlers Provide way to gracefully terminate or use spdlog in signal handlers Jul 7, 2020
@TamasFlorin
Copy link
Contributor Author

TamasFlorin commented Jul 7, 2020

First of all, thank your for all the work that you have put into this!

Thanks for the feedback :)

I will add it to the todo list to implement in spdlog somehow (probably similar to @tt4g suggestion).

Thank you @gabime ! Looking forward to it!

@TamasFlorin
Copy link
Contributor Author

TamasFlorin commented Jul 7, 2020

There are not many safe operations within the signal handler (see reference: std::signal - cppreference.com).
And spdlog does not support its use within signal handlers.

One workaround is to use std::condition_variable to call a function that is not signal safe outside the signal function.
Like this link example code, if you call the notification function of std::condition_variable in the signal function and call spdlog::shutdown() when the process thread receives the notification,
spdlog will now shutdown when a signal is received.

Thanks for the suggestion @tt4g ! I will look into it.

@qaler
Copy link

qaler commented Mar 9, 2021

Could you please provide an example code snippet of how to implement logs flushing when segfault occurs?

@tt4g
Copy link
Contributor

tt4g commented Mar 10, 2021

@qaler This is very simple example:

#include <atomic>
#include <csignal>
#include <iostream>

#include "spdlog/spdlog.h"

static std::atomic<bool> signalReceived = false;

void signal_handler(int signal)
{
    signalReceived = true;
}
 
int main()
{
    std::signal(SIGINT, signal_handler);

    for (;;) {
        if (signalReceived) {
            // Handle signal
            spdlog::error("Signal!!!");
            break;
        } else {
            // Main process.
            std::cout << "Main\n";
        }
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants