pthread_exit in signal handler causes segmentation fault - linux

The program below sets SIG_ALRM handler for the whole process, creates a thread, sends SIG_ALRM signal to new created thread.
In SIG_ALRM handler pthread_exit is called.
The result - segmentation fault.
If you sleep before sending signal - OK.
It looks like new thread has not been started at the moment of pthread_exit.
I tried to locate segmentation fault with gdb but couldn't reproduce the crash with gdb.
What causes segmentation fault?
Thanks!
#include <signal.h>
#include <pthread.h>
#include <iostream>
#include <cassert>
using namespace std;
void* threadFunc(void* arg) {
cout << "thread: started. sleeping..: " << pthread_self() << endl;
sleep(10);
cout << "thread: exit" << endl;
return NULL;
}
void alrm_handler(int signo) {
cout << "alrm_handler: " << pthread_self() << endl;
pthread_exit(NULL); //if comment - no segmentation fault
}
int main() {
cout << "main: " << pthread_self() << endl;
struct sigaction act;
act.sa_handler = alrm_handler;
act.sa_flags = 0;
sigemptyset(&act.sa_mask);
sigaction(SIGALRM, &act, NULL);
pthread_t t;
int rc = pthread_create(&t, NULL, threadFunc, NULL);
assert(rc == 0);
// usleep(1000); //if Uncomment - no segmentation fault
rc = pthread_kill(t, SIGALRM);
assert(rc == 0);
pthread_join(t, NULL);
cout << "main: exit" << endl;
return 0;
}
The output:
main: 140130531731232
alrm_handler: 140130504095488
Segmentation fault

pthread_exit is not async-signal-safe. You cannot call it from signal handlers unless you can be sure the signal handler is not interrupting an async-signal-unsafe function. In particular, the time between calling pthread_create and the entry to your new thread's start function must be considered async-signal-unsafe - this is never explicitly spelled out in the standard, but you can think of the new thread as still being "in pthread_create" (which is async-signal-unsafe) if you like.

Give change for thread initialization process to be completed. so just uncomment the below line is the right approach.
usleep(1000);

Related

Why sleep() in a thread cannot be interrupted by signal in my code?

#include <iostream>
#include <thread>
#include <signal.h>
#include <unistd.h>
void handler(int sig){
std::cout << "handler" << std::endl;
}
void func() {
sleep(100);
perror("sleep err:");
}
int main(void) {
signal(SIGINT, handler);
std::thread t(func);
pthread_kill(t.native_handle(), SIGINT);
perror("kill err:");
t.join();
return 0;
}
If I put sleep() inside main function, and send a signal by pressing ctrl+c, sleep will be interrupted and return immediately with perror() saying it's interrupted.
But with the code above, the "handler" in handler function will be printed, but sleep will not return and the program keeps running. The output of this program is:
kill err:: Success
handler
And if I replace sleep() with recvfrom(), recvfrom() will not be interrupted even it's inside the main thread.
#include <vector>
#include <string.h>
#include <netinet/in.h>
#include <errno.h>
#include <unistd.h>
void SigHandler(int sig){
std::cout << "handler" << std::endl;
}
int main(void) {
signal(SIGINT, SigHandler);
int bind_fd_;
if ((bind_fd_ = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
std::cout << "socket creation failed " << strerror(errno) << std::endl;
}
struct sockaddr_in servaddr;
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(12345);
if (bind(bind_fd_, reinterpret_cast<const struct sockaddr *>(&servaddr),
sizeof(servaddr)) < 0) {
std::cout << "socket bind failed " << strerror(errno) << std::endl;
}
struct sockaddr_in cliaddr;
socklen_t cliaddr_len = sizeof(cliaddr);
std::vector<char> buffer(10*1024*1024,0);
std::cout << "Wait for new request"<< std::endl;
int n = 0;
while (n == 0) {
std::cout << "before recvfrom" << std::endl;
n = recvfrom(bind_fd_, buffer.data(), buffer.size(), 0,
reinterpret_cast<struct sockaddr *>(&cliaddr), &cliaddr_len);
// sleep(100);
perror("recvfrom err: ");
std::cout << "recv " << n << " bytes from " << cliaddr.sin_port<< std::endl;
}
}
I don't know what is wrong with my code, hoping your help, thanks
At the time you direct the signal to the thread, that thread has not yet proceeded far enough to block in sleep(). Chances are that it has not even been scheduled for the first time. Change the code to something like
std::thread t(func);
sleep(5); // give t enough time to arrive in sleep()
pthread_kill(t.native_handle(), SIGINT);
and you'll see what you expect.
Note that using signals in a multithreaded program is not usually a good idea because certain aspects are undefined/not-so-clearly defined.
Note also that it is not correct to use iostreams inside a signal handler. Signal handlers run in a context where pretty much nothing is safe to do, much like an interrupt service routine on bare metal. See here for a thorough explanation of that matter.

How would I stop a std::thread in a controlled manner

I have a program where I start multiple, long running threads (such as a REST-API). On primed signals (e.g SIGHUP) I would like to be able to shut down all threads cleanly (by waiting for them to exit). Below follows some code from a thispointer article that illustrated a good idea on how to do this
#include <thread>
#include <iostream>
#include <assert.h>
#include <chrono>
#include <future>
void threadFunction(std::future<void> futureObj)
{
std::cout << "Thread Start" << std::endl;
while (futureObj.wait_for(std::chrono::milliseconds(1)) ==
std::future_status::timeout)
{
std::cout << "Doing Some Work" << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}
std::cout << "Thread End" << std::endl;
}
int main()
{
// Create a std::promise object
std::promise<void> exitSignal;
//Fetch std::future object associated with promise
std::future<void> futureObj = exitSignal.get_future();
// Starting Thread & move the future object in lambda function by reference
std::thread th(&threadFunction, std::move(futureObj));
//Wait for 10 sec
std::this_thread::sleep_for(std::chrono::seconds(10));
std::cout << "Asking Thread to Stop" << std::endl;
//Set the value in promise
exitSignal.set_value();
//Wait for thread to join
th.join();
std::cout << "Exiting Main Function" << std::endl;
return 0;
}
However, as one might have noticed this concept has a critical drawback: the exitSignal will have to be emitted before th.join() is called.
In a situation where one wants to listen to a signal, e.g using signal(SIGHUP, callback) this is of course impractical.
My question is: are there better concepts for shutting down multiple threads? How would I go about them? I think using a promise is not a bad idea, I just haven't found a way with it to solve my problem.
You can use std::notify_all_at_thread_exit() on a std::condition_variable.
Here is an example:
#include <mutex>
#include <thread>
#include <condition_variable>
#include <cassert>
#include <string>
std::mutex m;
std::condition_variable cv;
bool ready = false;
std::string result; // some arbitrary type
void thread_func()
{
thread_local std::string thread_local_data = "42";
std::unique_lock<std::mutex> lk(m);
// assign a value to result using thread_local data
result = thread_local_data;
ready = true;
std::notify_all_at_thread_exit(cv, std::move(lk));
} // 1. destroy thread_locals;
// 2. unlock mutex;
// 3. notify cv.
int main()
{
std::thread t(thread_func);
t.detach();
// do other work
// ...
// wait for the detached thread
std::unique_lock<std::mutex> lk(m);
cv.wait(lk, [] { return ready; });
// result is ready and thread_local destructors have finished, no UB
assert(result == "42");
}
Source: cppreference.com

Deadlock after notify_one() (notifying thread locks mutex)

I have following problem. I have some multiple threads that do some work and one main thread that wakes them up when work is available. So far, I have managed to write some code using conditional variables and mutexes and most of the time this works okay, but from time to time, notifying thread will lock the mutex right after call notify_one(), thus blocking the notified thread and deadlocking.
I have written minimal code to illustrate this situation.
#include <iostream>
#include <thread>
#include <condition_variable>
std::mutex lock;
std::condition_variable cv;
void foo() {
std::cout << "Thread: Entering doWork()" << std::endl;
std::unique_lock<std::mutex> l(lock);
std::cout << "Thread: Acquired lock, going to wait." << std::endl;
cv.wait(l , []{return true;});
std::cout << "Thread: Done waiting, exit." << std::endl;
}
int main(void) {
std::unique_lock<std::mutex> l(lock);
std::cout << "MAIN: Creating thread." << std::endl;
std::thread t(foo);
std::cout << "MAIN: Unlocking mutex." << std::endl;
l.unlock();
std::cout << "MAIN: Notifying thread." << std::endl;
cv.notify_one();
//std::this_thread::sleep_for(std::chrono::seconds(1));
l.lock();
std::cout << "MAIN: Acquired lock." << std::endl;
std::cout << "MAIN: Joining thread." << std::endl;
t.join();
return 0;
}
In ideal situation, the output should be
MAIN: Creating thread.
MAIN: Unlocking mutex.
Thread: Entering doWork()
Thread: Acquired lock, going to wait.
MAIN: Notifying thread.
Thread: Done waiting, exit.
MAIN: Acquired lock.
MAIN: Joining thread.
but more often than not it is
MAIN: Creating thread.
MAIN: Unlocking mutex.
MAIN: Notifying thread.
MAIN: Acquired lock.
MAIN: Joining thread.
Thread: Entering doWork()
Is there any better way to eliminate chance of deadlock except of adding sleep into notifying thread (which I don't want to do)? Thank you in advance.
It's "condition variable" not "conditional variable", and the reason it's called that is that you use it to wait on some condition.
You aren't doing that, you just wait on a lambda that always returns true, and that's the cause of your problem. That and the fact your main thread is holding the lock all the time (why?!)
Sometimes the main thread runs the unlock, the notify_one, and the lock quickly, before the foo thread has even started. That means the foo thread misses the notification, then tries to acquire the lock, but can't because the main thread has it.
A condition variable is not like a semaphore, the notify_one` call does not set a state that can be detected later. If the condition variable isn't waiting when the notify_one call happens then it misses it, and it is gone forever. If you miss the notification and then sleep you will never wake up.
The solution is not to add arbitrary sleeps, that doesn't solve anything (ever!)
The correct solution is to have a condition that is tested, and to stop holding the lock when you're not updating any shared data. In the example below the condition being tested is "is the boolean ready true?" and the foo thread will wait until that condition is true. The main thread sets the variable, making the condition true, and then notifies the other thread that it should re-check the condition.
#include <iostream>
#include <thread>
#include <condition_variable>
std::mutex lock;
std::condition_variable cv;
bool ready = false;
void foo() {
std::cout << "Thread: Entering doWork()" << std::endl;
std::unique_lock<std::mutex> l(lock);
std::cout << "Thread: Acquired lock, going to wait." << std::endl;
cv.wait(l , []{return ready;});
std::cout << "Thread: Done waiting, exit." << std::endl;
}
int main(void) {
std::cout << "MAIN: Creating thread." << std::endl;
std::thread t(foo);
{
std::cout << "MAIN: Locking mutex." << std::endl;
std::unique_lock<std::mutex> l(lock);
ready = true;
}
std::cout << "MAIN: Notifying thread." << std::endl;
cv.notify_one();
std::cout << "MAIN: Joining thread." << std::endl;
t.join();
}

Thread running between fork and exec blocks other thread read

While studying the possibility of improving Recoll performance by using vfork() instead of fork(), I've encountered a fork() issue which I can't explain.
Recoll repeatedly execs external commands to translate files, so that's what the sample program does: it starts threads which repeatedly execute "ls" and read back the output.
The following problem is not a "real" one, in the sense that an actual program would not do what triggers the issue. I just stumbled on it while having a look at what threads were stopped or not between fork()/vfork() and exec().
When I have one of the threads busy-looping between fork() and exec(), the other thread never completes the data reading: the last read(), which should indicate eof, is blocked forever or until the other thread's looping ends (at which point everything resumes normally, which you can see by replacing the infinite loop with one which completes). While read() is blocked, the "ls" command has exited (ps shows <defunct>, a zombie).
There is a random aspect to the issue, but the sample program "succeeds" most of the time. I tested with Linux kernels 3.2.0 (Debian), 3.13.0 (Ubuntu) and 3.19 (Ubuntu). Works on a VM, but you need at least 2 procs, I could not make it work with one processor.
Here follows the sample program, I can't see what I'm doing wrong.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <memory.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <pthread.h>
#include <iostream>
using namespace std;
struct thread_arg {
int tnum;
int loopcount;
const char *cmd;
};
void* task(void *rarg)
{
struct thread_arg *arg = (struct thread_arg *)rarg;
const char *cmd = arg->cmd;
for (int i = 0; i < arg->loopcount; i++) {
pid_t pid;
int pipefd[2];
if (pipe(pipefd)) {
perror("pipe");
exit(1);
}
pid = fork();
if (pid) {
cerr << "Thread " << arg->tnum << " parent " << endl;
if (pid < 0) {
perror("fork");
exit(1);
}
} else {
// Child code. Either exec ls or loop (thread 1)
if (arg->tnum == 1) {
cerr << "Thread " << arg->tnum << " looping" <<endl;
for (;;);
//for (int cc = 0; cc < 1000 * 1000 * 1000; cc++);
} else {
cerr << "Thread " << arg->tnum << " child" <<endl;
}
close(pipefd[0]);
if (pipefd[1] != 1) {
dup2(pipefd[1], 1);
close(pipefd[1]);
}
cerr << "Thread " << arg->tnum << " child calling exec" <<
endl;
execlp(cmd, cmd, NULL);
perror("execlp");
_exit(255);
}
// Parent closes write side of pipe
close(pipefd[1]);
int ntot = 0, nread;
char buf[1000];
while ((nread = read(pipefd[0], buf, 1000)) > 0) {
ntot += nread;
cerr << "Thread " << arg->tnum << " nread " << nread << endl;
}
cerr << "Total " << ntot << endl;
close(pipefd[0]);
int status;
cerr << "Thread " << arg->tnum << " waiting for process " << pid
<< endl;
if (waitpid(pid, &status, 0) != -1) {
if (status) {
cerr << "Child exited with status " << status << endl;
}
} else {
perror("waitpid");
}
}
return 0;
}
int main(int, char **)
{
int loopcount = 5;
const char *cmd = "ls";
cerr << "cmd [" << cmd << "]" << " loopcount " << loopcount << endl;
const int nthreads = 2;
pthread_t threads[nthreads];
for (int i = 0; i < nthreads; i++) {
struct thread_arg *arg = new struct thread_arg;
arg->tnum = i;
arg->loopcount = loopcount;
arg->cmd = cmd;
int err;
if ((err = pthread_create(&threads[i], 0, task, arg))) {
cerr << "pthread_create failed, err " << err << endl;
exit(1);
}
}
void *status;
for (int i = 0; i < nthreads; i++) {
pthread_join(threads[i], &status);
if (status) {
cerr << "pthread_join: " << status << endl;
exit(1);
}
}
}
What's happening is that your pipes are getting inherited by both child processes instead of just one.
What you want to do is:
Create pipe with 2 ends
fork(), child inherits both ends of the pipe
child closes the read end, parent closes the write end
...so that the child ends up with just one end of one pipe, which is dup2()'ed to stdout.
But your threads race with each other, so what can happen is this:
Thread 1 creates pipe with 2 ends
Thread 0 creates pipe with 2 ends
Thread 1 fork()s. The child process has inherited 4 file descriptors, not 2!
Thread 1's child closes the read end of the pipe that thread 1 opened, but it keeps a reference to the read end and write end of thread 0's pipe too.
Later, thread 0 waits forever because it never gets an EOF on the pipe it is reading because the write end of that pipe is still held open by thread 1's child.
You will need to define a critical section that starts before pipe(), encloses the fork(), and ends after close() in the parent, and enter that critical section from only one thread at a time using a mutex.

Simple Detached pthread does not cancel! (cout blocks and interleaves even if mutexed)

I have a hard problem here, which I can not solve and do not find the right answer on the net:
I have created a detached thread with a clean up routing, the problem is that on my Imac and Ubuntu 9.1 (Dual Core). I am not able to correctly cancel the detached thread in the fallowing code:
#include <iostream>
#include <pthread.h>
#include <sched.h>
#include <signal.h>
#include <time.h>
pthread_mutex_t mutex_t;
using namespace std;
static void cleanup(void *arg){
pthread_mutex_lock(&mutex_t);
cout << " doing clean up"<<endl;
pthread_mutex_unlock(&mutex_t);
}
static void *thread(void *aArgument)
{
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL);
pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED,NULL);
pthread_cleanup_push(&cleanup,NULL);
int n=0;
while(1){
pthread_testcancel();
sched_yield();
n++;
pthread_mutex_lock(&mutex_t);
cout << " Thread 2: "<< n<<endl; // IF I remove this endl; --> IT WORKS!!??
pthread_mutex_unlock(&mutex_t);
}
pthread_cleanup_pop(0);
return NULL;
}
int main()
{
pthread_t thread_id;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
int error;
if (pthread_mutex_init(&mutex_t,NULL) != 0) return 1;
if (pthread_create(&thread_id, &attr, &(thread) , NULL) != 0) return 1;
pthread_mutex_lock(&mutex_t);
cout << "waiting 1s for thread...\n" <<endl;
pthread_mutex_unlock(&mutex_t);
int n =0;
while(n<1E3){
pthread_testcancel();
sched_yield();
n++;
pthread_mutex_lock(&mutex_t);
cout << " Thread 1: "<< n<<endl;
pthread_mutex_unlock(&mutex_t);
}
pthread_mutex_lock(&mutex_t);
cout << "canceling thread...\n" <<endl;
pthread_mutex_unlock(&mutex_t);
if (pthread_cancel(thread_id) == 0)
{
//This doesn't wait for the thread to exit
pthread_mutex_lock(&mutex_t);
cout << "detaching thread...\n"<<endl;
pthread_mutex_unlock(&mutex_t);
pthread_detach(thread_id);
while (pthread_kill(thread_id,0)==0)
{
sched_yield();
}
pthread_mutex_lock(&mutex_t);
cout << "thread is canceled";
pthread_mutex_unlock(&mutex_t);
}
pthread_mutex_lock(&mutex_t);
cout << "exit"<<endl;
pthread_mutex_unlock(&mutex_t);
return 0;
}
When I replace the Cout with printf() i workes to the end "exit" , but with the cout (even locked) the executable hangs after outputting "detaching thread...
It would be very cool to know from a Pro, what the problem here is?.
Why does this not work even when cout is locked by a mutex!?
THE PROBELM lies in that COUT has a implicit cancelation point!
We need to code like this:
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL);
pthread_testcancel();
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,NULL);
and make the thread at the beginning :
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,NULL);
That ensures that only pthread_cancel() has a cancelation point...
Try commenting out the line pthread_detach(thread_id); and run it. You are creating the thread as detached with your pthread_attr_t.
Either that, or try passing NULL instead of &attr in the pthread_create (so that the thread is not created detached) and run it.
I would guess that if the timing is right, the (already detached) thread is gone by the time the main thread attempts the pthread_detach, and you are going off into Never Never Land in pthread_detach.
Edit:
If cout has an implicit cancelation point as Gabriel points out, then most likely what happens is that the thread cancels while holding the mutex (it never makes it to pthreads_unlock_mutex after the cout), and so anybody else waiting on the mutex will be blocked forever.
If the only resource you need to worry about is the mutex, you could keep track of whether or not your thread has it locked and then unlock it in the cleanup, assuming that cleanup runs in the same thread.
Take a look here, page 157 on: PThreads Primer.

Resources