Why does pthread_exit(0) hangs the program? - c

Running the following C code causes the program to hang, and does not respond to signals (including CTRL-C).
int main()
{
pthread_exit(0);
return 0;
}
Any idea why?
The behaviour is normal when other threads have been created and are running, but I would like to know if I always have to check that before using pthread_exit(0).
EDIT:
This is the complete code that hangs. However, I was building with glib (-lglib-2.0). Using simply cc -o foo foo.c works as expected.

Your entire use case is described in the notes of the pthread_exit man page.
In your case, as you correctly edited your OP, glib started another thread. You exited the main thread and the other thread kept running. You labeled this as a hang.
In general, if you want to exit the application in full, just use exit or return from main().
Only when you need additional magic (rarely) like detached threads, use pthread_exit() on the main thread.

Related

Is it possible to get backtrace on application exit?

I have an linux(ARM) multithread application. How can I get the backtraces (for all threads) of the app on exit (not a crash).
Note: I can’t use gdb with catch syscall because of not supported architecture for this feature.
I tried to set breakpoints with gdb on exit and _exit, but no success.
Returning from main() is not guaranteed to call either exit() or _exit(). That's an internal implementation detail that isn't covered by the C standard.
You can add an exit handler function using atexit() and then set a gdb breakpoint in that function.
#include <stdlib.h>
.
.
.
static void myExitHandler( void )
{
write( STDERR_FILENO, "in exit handler\n",
strlen( "in exit handler\n" ) );
}
And in your main():
atexit( myExitHandler );
Then you should be able to set a breakpoint in myExitHandler() and it should be triggered when your process exits.
If you need to get backtraces for all threads programmatically without using gdb, if your program keeps track of its threads (it sure should...) you can pass the thread ids to your exit handler and use something like libunwind to get the backtraces. See Getting a backtrace of other thread for some ways to do that.
But as noted in the comments, if your threads are actually working, simply exiting the process entirely can cause problems such as data corruption.

How to use exit() safely from any thread

According to the man page (2) the exit function is not thread safe : MT-Unsafe race:exit, this is because this function tries to clean up resources (flush data to the disk, close file descriptors, etc...) by calling callbacks registered using on_exit and atexit. And I want my program to do that ! (one of my thread keeps a fd open during the whole program's lifespan so _exit is not an option for me because I want all the data to be written to the output file)
My question is the following : if I'm being careful and I don't share any sensible data (like a fd) between my threads, is it "acceptable" to call exit in a multi-threaded program ? Note that I'm only calling exit if an unrecoverable error occurs. Yet, I can't afford having a segfault while the program tries to exit. The thing is, an unrecoverable error can happen from any thread...
I was thinking about using setjmp/longjmp to kill my threads "nicely" but this would be quite complex to do and would require many changes everywhere in my code.
Any suggestions would be greatly appreciated. Thanks ! :)
EDIT : Thanks to #Ctx enlightenment, I came up with the following idea :
#define EXIT(status) do { pthread_mutex_lock(&exit_mutex); exit(status); } while(0)
Of course the exit_mutex must be global (extern).
The manpage states that
The exit() function uses a global variable that is not protected, so it is not thread-safe.
so it won't help, if you are being careful in any way.
But the problem documented is a race condition: MT-Unsafe race:exit
So if you make sure, that exit() can never be called concurrently from two threads, you should be on the safe side! You can make this sure by using a mutex for example.
A modern cross-platform C++ solution could be:
#include <cstdlib>
#include <mutex>
std::mutex exit_mutex;
[[noreturn]] void exit_thread_safe(const int status)
{
exit_mutex.lock();
exit(status);
}
The mutex ensures that exit is never called by 2 (or more) different threads.
However, I still question the reason behind even caring about this. How likely is a multi-threaded call to exit() and which bad things can even realistically happen?
EDIT:
Using std::quick_exit avoids the clang diagnostic warning.
It can't be done: even if no data is shared between threads at first, data must be shared between a thread and its cleanup function. The function should run only after the thread has stopped or reached a safe point.

How to kill process completely from a thread in Linux (C)

I have a C code that runs on Linux that creates a certain amount of threads. In one of the threads, I want it so that if it runs into a certain condition, it should terminate the entire process. I looked up the exit() command but didn't really understand how to use it.
There's little not to understand about exit(). Just do:
exit(EXIT_FAILURE);
and gone's your process.
EXIT_FAILURE becomes the exit status of your program; this is the same as returning a value from main().
Since you're all in one process, though multiple threads, just hitting exit will kill the lot.

Creating a new thread (C, Windows)

OK, I'm a bit confused here. The following code works:
HANDLE CreateSideThread()
{
DWORD dwGenericThread;
HANDLE hThread1 = CreateThread(NULL, 0, CallBackFunc, NULL, 0, &dwGenericThread);
return hThread1;
}
int main()
{
HANDLE Thread1;
Thread1 = CreateSideThread();
WaitForSingleObject(hThread1, INFINITE);
SomeOtherFunction();
return 0;
}
The program does other things but you get the idea. It basically creates a new thread and executes whatever it is in CallBackFunc (which is an endless loop that check db status).
Now, if I remove WaitForSingleObject() then the program will not even try CallBackFunc once and execute SomeOtherFunction().
What's the point then of a thread? I mean, i'm confused here.
What I am trying to do is call that thread with the check for the database status and keep that thread going while I continue with my program, calling other functions.
What am I doing wrong?
Please post a sample snippet.
Thanks
Without the WaitForSingleObject, your call to SomeOtherFunction() probably returns quickly enough for the program to exit before the new thread even gets a chance to run once.
When a C program returns from its main() function, the runtime system calls exit() for you. This forcibly exits your program even if other threads are trying to run at the same time. This is in contrast to other languages like Java for example, where exiting the main thread will not exit the process until all other (non-daemon) threads have finished running too.
Threads are typically used for doing background work and freeing up the calling thread to do other things.
Normally, the behavior you describe (calling SomeOtherFunction()) is exactly what you'd want: I am going to kick of a background 'job' and go about my life.
It would appear that your example is just fine - though if you merely return from main() your thread will of course terminate (as it's owned by the parent process).
Maybe some more detail on why what you're doing isn't what you expect to happen?
What you're finding is that the main thread completes before you notice CallbackFunc is called. When you have the Wait call in, the main thread is blocked until the new thread finishes and so you see the thread func being executed.
Threads are not as cheap as you think, if you replace the SomeOtherFunction with something that takes a long enough time to run, you'll see your thread function being called even without the Wait call.
CallBackFunc will of course be called, but there is no guarantee, when your stared threads will be up and running. They will be working once, but its unpredictable when the start doing so. Thats the job and property of the systems scheduler. In your case they do not anything when the second function is already called.

What makes a pthread defunct?

i'm working with a multi-threaded program (using pthreads) that currently create a background thread (PTHREAD_DETACHED) and then invokes pthread_exit(0). My problem is that the process is then listed as "defunct" and curiously do not seems to "really exists" in /proc (which defeats my debugging strategies)
I would like the following requirements to be met:
the program should run function A in a loop and function B once
given the PID of the program /proc/$pid/exe, /proc/$pid/maps and /proc/$pid/fd must be accessible (when the process is defunct, they are all empty or invalid links)
it must be possible to suspend/interrupt the program with CTRL+C and CTRL+Z as usual
edit: I hesitate changing the program's interface for having A in the "main" thread and B in a spawned thread (they are currently in the other way). Would it solve the problem ?
You can either suspend the execution of the main process waiting for a signal, or don't detach the thread (using the default PHTREAD_CRATE_JOINABLE) waiting for its termination with a pthread_join().
Is there a reason you can't do things the other way round: have the main thread run the loop, and do the one-off task in the background thread?
Not the most elegant design but maybe you could block the main thread before exiting with:
while(1) {
pause();
}
Then you can install a signal handler for SIGINT and SIGTERM that breaks the loop. The easiest way for that is: exit(0) :-).

Resources