-
Notifications
You must be signed in to change notification settings - Fork 2.1k
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
Using call_once could lead to infinite loop in fatal signal handler ? #1080
Comments
I'm not sure I fully understand the problem. Do you have an example that demonstrates the issue? |
sorry, i write a demo only for test. #include <cstdio>
#include <string.h>
#include <pthread.h>
#include <csignal>
#include <unistd.h>
#include <limits.h>
#include <mutex>
using namespace std;
void *signal_thread(void *arg) {
int i = 0;
while(1) {
i++;
printf("child 1 %d\n", i);
if (i > 3) {
raise(SIGSEGV);
}
sleep(5);
}
}
static std::once_flag signaled;
void FailureSignalHandler(int sig) {
int i = 0;
while(i < INT_MAX) {
i++;
}
raise(SIGABRT);
struct sigaction sig_action;
memset(&sig_action, 0, sizeof(sig_action));
sigemptyset(&sig_action.sa_mask);
sig_action.sa_handler = SIG_DFL;
sigaction(sig, &sig_action, NULL);
printf("x %d\n", sig);
kill(getpid(), sig);
}
static void FatalSignalHandler(int sig, siginfo_t* info, void* data) {
printf("sig %d\n", sig);
std::call_once(signaled, &FailureSignalHandler, sig);
printf("%d\n", sig);
}
int main(int argc, char *argv[]) {
pthread_t tid;
int rc;
struct sigaction sig_action;
memset(&sig_action, 0, sizeof(sig_action));
sig_action.sa_flags = SA_SIGINFO;
sig_action.sa_sigaction = FatalSignalHandler;
sigemptyset(&sig_action.sa_mask);
sigaction(SIGSEGV, &sig_action, nullptr);
sigaction(SIGABRT, &sig_action, nullptr);
rc = pthread_create(&tid, NULL, signal_thread, NULL);
if (rc != 0) {
exit(1);
}
pthread_join(tid, nullptr);
} i compile this code with gcc 7 and run in a centos 7 (it occurs infinite loop i'm not sure if we should consider this scenario in this patch |
I do not observe an infinite loop. In fact, it is |
yeah ,
It did not run Here is gdb info, single thread doesn't quit so in main thread
sorry i don't quite understand how the deadlock you mentioned occurs. |
That's because your code installs a struct sigaction sig_action;
memset(&sig_action, 0, sizeof(sig_action));
sig_action.sa_flags = SA_SIGINFO;
sig_action.sa_sigaction = FatalSignalHandler;
sigemptyset(&sig_action.sa_mask);
sigaction(SIGSEGV, &sig_action, nullptr);
sigaction(SIGABRT, &sig_action, nullptr); that infinitely raises However, I'm not sure how this is related to the |
Since i saw that the signal handlers of SIGSEGV and SIGABRT were also registered in glog, I thought that if another signal (in above demo is SIGABRT) is triggered during the execution of signal handler, an infinite loop may occur. However, i really don't know if this scenario needs to be considered cause i haven't reproduced it yet, it's just a theoretical consideration. |
To avoid speculations a test case that actually uses glog would be helpful. Either way, I do not see any relation to |
sure, it better to write an UT. Anyway, the above demo register SIGSEGV & SIGABRT handler function like glog signal handler , both glog and demo use I will try to write an test case ASAP. |
Let me close this issue as there is nothing to address right now. |
Hi glog experts,
i wonder if using call_once (in this patch) which leading to infinite loop in such a scenario:
In short, another fatal signal is triggered in the signal handler which may cause an infinite loop.
@sergiud #1026
The text was updated successfully, but these errors were encountered: