I'm working on a multithreaded C++ application in Linux with FreeGLUT. Oddly enough, calling exit() in one of my threads results in an onexit() callback being called and completed, but fails to exit my program. Instead it hangs in a select() call in the GLUT library, according to GDB.
I also have a keyboard callback that exits when I press 'q'. GLUT exits fine if I press 'q' while the program is hanging.
No one seems to be having similar problems. Documentation says that exit() is supposed to close an entire process, and not just a thread, so it's not that. I'm stumped. Do you have any ideas?
EDIT: I've found the problem. I was wrong that the exit handler had finished. A library function call was waiting on a mutex that was already locked at the time that exit() was called. GLUT just took advantage of the free time. Thank you all for your responses.
In C++03
Note: exit() is a C function.
C as a language does not have the concept of threads at the language level.
Threads are usually added to C via a library support. So you need to read the library documentation of the affects of calling exit() from a thread that is not the main thread.
It is probably not portable across threading implementations.
Your best bet is to only call exit() from the main thread.
In a child thread you should probably just set some state that is viewed by the main thread. Let the main thread see this state and call exit manually. Note even calling exit on the man thread may hang some threading libraries if their are child threads still running. So best to get the main thread to wait for all children before exiting if you want your code to be portable.
In C++11
Now that C++11 has entered the since with explicit threading in the language there is more to it. See n3376 Section 18.4.1 [cstdint.syn] Paragraph 8
The function exit() has additional behavior in this International Standard:
— First, objects with thread storage duration and associated with the current thread are destroyed. Next, objects with static storage duration are destroyed and functions registered by calling atexit are called.
See 3.6.3 for the order of destructions and calls. (Automatic objects are not destroyed as a result of calling exit().)
If control leaves a registered function called by exit because the function does not provide a handler for a thrown exception, std::terminate() shall be called (15.5.1).
— Next, all open C streams (as mediated by the function signatures declared in ) with unwritten buffered data are flushed, all open C streams are closed, and all files created by calling tmpfile() are removed.
— Finally, control is returned to the host environment. If status is zero or EXIT_SUCCESS, an implementation-defined form of the status successful termination is returned. If status is EXIT_FAILURE, an implementation-defined form of the status unsuccessful termination is returned. Otherwise the status returned is implementation-defined.
Related
I have written a signal handler to handle a SIG, and I want to kill the process if I get too many of it. So, which of the following code is better, or should I use them both?
exit(-1); // or some other exit code
kill(getpid(), SIGKILL);
You probably don't want either one, but what you do want is much closer to exit than to kill.
kill is something else coming in from the outside, and forcibly destroying a process. exit is the process itself deciding to quit executing. The latter is generally preferable.
As to why exit isn't the right answer either: most C++ code depends on destructors to clean up objects as you exit from a scope. If you call exit, that won't generally happen--you call exit, it exits to the OS, and no destructors get called in between (except things registered with onexit).
Instead, you generally want to throw an exception that's typically only caught in main, and exits gracefully when it is caught:
int main() {
try {
do_stuff();
}
catch(time_to_die const &) {
}
}
The advantage in this case is that when you do a throw time_to_die;, it automatically unwinds the stack, executing the destructors for all local objects as it goes. When it gets back to main, you get a normal exit, with all destructors having executed, so (assuming proper use of RAII) all your files, network connections, database connections, etc., have been closed as expected, any caches flushed, and so on, so you get a nice, graceful exit.
Short summary: as a rule of thumb, C++ code should never call exit. If your code is completely stuck in a crack, and you want to exit immediately, you want to call abort. If you want a semi-normal exit, do it by throwing an exception that will get you back to main so you can clean things and up and exit gracefully.
Difference between exit and kill in C++
One difference is that kill function is not specified in the C++ standard library. It is merely specified in POSIX. exit is standard C++.
Another difference is that kill(getpid(), SIGKILL) will cause the operating system terminates the process forcefully. exit instead performs cleanup (by calling a atexit callback, and flushing streams etc.) and terminates the execution voluntarily.
So, which of the following code is better, or should I use them both?
Depends on the use case, but usually exit is more sensible, since one usually wants the cleanup that it provides.
I would recommend exit(1).
Typically, an app would want to terminate gracefully if at all possible. SIGKILL is an instant death for your process - your exit handlers won't be called, for example. But in your case, you also have to call the getpid as well as the kill itself. exit instantly initiates the graceful exit process. It's the right choice for your needs.
There's rarely a good architectural reason to use SIGKILL in general. there's so many signals (http://man7.org/linux/man-pages/man7/signal.7.html in POSIX, you have SIGINT, SIGTERM, ... ) and to reiterate, there's no reason not to die gracefully if you can.
We have some c++ code that can make calls to exit(3) through the users API. My assumption is that we are not properly unwinding stacks and that this considered bad in c++. Also there is a big c++ library involved that must be considered a black box.
I want to patch this, and also have an idea how, but don't know how to observe and compare the change. Can I make this somehow visible? Possibly on OS X?
exit() apparently does some cleanup. This is described in section 18.5 [support.start.term] of the standard, but the frequently correct site www.cplusplus.com summarizes it.
So it says objects with static storage or thread storage will be cleaned up, as will the entire I/O system (files will be flushed, etc).
But there are other ways to exit without running the C++ cleanup. For example, if it is a library that calls exit and it is a C language library (not C++) then it may or may not do the C++ cleanup. Or there are calls to abort or quick_exit. And, too, if you call the OS directly (e.g., ExitProcess() on Windows) then the process exits immediately and no C++ cleanup is done.
If you want to make the behavior visible: Make a object with a destructor that does something interesting - like log a message somewhere. Or maybe when it is constructed it creates a file with a certain name and when destructed it deletes it. Declare an instance this object in your main(). Declare another one (with a different message) at static scope. So now you have an effect observable in your environment.
The following is from 18.5 of N4140 (2014-10-07):
[[noreturn]] void exit(int status)
8 The function exit() has additional behavior in this International Standard:
(8.1) First, objects with thread storage duration and associated with the current
thread are destroyed. Next,objects with static storage duration are destroyed
and functions registered by calling `atexit` are called. See 3.6.3 for the
order of destructions and calls. (Automatic objects are not destroyed as a
result of calling `exit()`.) If control leaves a registered function called by
`exit` because the function does not provide a handler for a thrown exception,
`std::terminate()` shall be called (15.5.1).
(8.2) Next, all open C streams (as mediated by the function signatures declared in
`<cstdio>`) with unwritten buffered data are flushed, all open C streams are
closed, and all files created by calling `tmpfile()` are removed.
(8.3) Finally, control is returned to the host environment. If `status` is zero or
`EXIT_SUCCESS`, an implementation-defined form of the status _successful
termination_ is returned. If `status` is `EXIT_FAILURE`, an implementation-
defined form of the status _unsuccessful termination_ is returned. Otherwise
the status returned is implementation-defined.
I'm used to work with good old WinAPI call CreateThread(), and check thread's status using the waiting function, e.g WaitForSingleObject(), Once thread thread is signaled with WAIT_OBJECT_0, i close it using CloseHandle().
Recently I've decided to move to beginthread and somehow avoid the risks of uninitialized crt and accidental memory leaks that may happen.
Doing that got me confused.
What's the exact purpose of endthread()? why when i call CloseHandle() in the main function, after thread's execution, CloseHandle() crashes with invalid handle?
Should i ever close the handle returned by beginthread?
endthread, As i understood is invoked automatically by the thread once my function goes out of scope, so should i call it anyway just before i get out of scope?
According to msdn, endthread already calls CloseHandle() 1.From where does the thread obtain a reference / instance to its handle. 2. If i do insist on using endthread(), should it be the last command in the thread?
thanks
EDIT: MSDN paper describing the leaks, here.
As stated in the comments by David Hefferman you can simply change your code back to using CreateThread. The Visual C++ runtime (CRT) will automatically initialize the CRT's per thread data the first time you use a function that uses the per thread data.
The CRT will also automatically free the per thread data when a thread ends, so using CreateThread won't cause memory leaks. There is one exception, if all of the following conditions are true then per thread data isn't automatically freed:
You're building an executable, not a DLL
You're linking against the static version of the CRT library (LIBCMT.LIB) instead of the DLL version (MSVCRT.LIB)
The executable you built is run under Windows XP (or an earlier version of Windows).
Note that even if all this true in your case, the memory leak isn't going to be significant unless you're creating a long lived application that creates and destroys hundreds of thousands of threads over its life time.
If you still want to use the CRTs thread creation functions (_beginthread/_beginthreadex) you should follow these guidelines:
Never use the handle returned by _beginthread. With _beginthread the thread handle is automatically closed when the thread exits, which can potentially happen before _beginthread even returns. You can't use it with WaitForSingleObject safely because the thread might have already exited before you call this function. If you want to use the thread handle for anything use _beginthreadex instead.
You should never close the handle returned by _beginthread. The CRT will do it automatically, and as described in the previous point, may do so before you have chance to.
You should always close the handle returned by _beginthreadex when you no longer need it. The CRT won't do this automatically for you, so it's your own responsibility.
Don't call _endthread or _endthreadex unless you want to quickly and abnormally terminate the thread. While the CRT will free its own per thread data, none of the C++ destructors for any of the thread's objects will be called. It behaves similarly to how _exit ends the process without calling destructors.
The normal means of ending a thread should be by returning from the function passed as an argument to _beginthread or _beginthreadex. This will result in C++ destructors being called as a normal part of the function return.
I am getting a SEGV in C++ that I cannot easily reproduce (it occurs in about one in 100,000 test runs) in my call to pthread_join() as my application is shutting down. I checked the value of errno and it is zero. This is running on Centos v4.
Under what conditions would pthread_join() get a SEGV? This might be some kind of race condition since it is extremely rare. One person suggests I should not be calling pthread_detach() and pthread_exit(), but I am not clear on why.
My first working hypothesis was that pthread_join() is being called while pthread_exit() is still running in the other thread and that this somehow leads to a SEGV, but many have stated this is not an issue.
The failing code getting SEGV in the main thread during application exit looks roughly like this (with error return code checking omitted for brevity):
// During application startup, this function is called to create the child thread:
return_val = pthread_create(&_threadId, &attr,
(void *(*)(void *))initialize,
(void *)this);
// Apparently this next line is the issue:
return_val = pthread_detach(_threadId);
// Later during exit the following code is executed in the main thread:
// This main thread waits for the child thread exit request to finish:
// Release condition so child thread will exit:
releaseCond(mtx(), startCond(), &startCount);
// Wait until the child thread is done exiting so we don't delete memory it is
// using while it is shutting down.
waitOnCond(mtx(), endCond(), &endCount, 0);
// The above wait completes at the point that the child thread is about
// to call pthread_exit().
// It is unspecified whether a thread that has exited but remains unjoined
// counts against {PTHREAD_THREADS_MAX}, hence we must do pthread_join() to
// avoid possibly leaking the threads we destroy.
pthread_join(_threadId, NULL); // SEGV in here!!!
The child thread which is being joined on exit runs the following code which begins at the point above where releaseCond() is called in the main thread:
// Wait for main thread to tell us to exit:
waitOnCond(mtx(), startCond(), &startCount);
// Tell the main thread we are done so it will do pthread_join():
releaseCond(mtx(), endCond(), &endCount);
// At this point the main thread could call pthread_join() while we
// call pthread_exit().
pthread_exit(NULL);
The thread appeared to come up properly and no error codes were produced during its creation during application startup and the thread performed its task correctly which took around five seconds before the application exited.
What might cause this rare SEGV to occur and how might I program defensively against it. One claim is that my call to pthread_detach() is the issue, if so, how should my code be corrected.
Assuming:
pthread_create returns zero (you are checking it, right?)
attr is a valid pthread_attr_t object (How are you creating it? Why not just pass NULL instead?)
attr does not specify that the thread is to be created detached
You did not call pthread_detach or pthread_join on the thread somewhere else
...then it is "impossible" for pthread_join to fail, and you either have some other memory corruption or a bug in your runtime.
[update]
The RATIONALE section for pthread_detach says:
The *pthread_join*() or *pthread_detach*() functions should eventually be
called for every thread that is created so that storage associated
with the thread may be reclaimed.
Although it does not say these are mutually exclusive, the pthread_join documentation specifies:
The behavior is undefined if the value specified by the thread
argument to *pthread_join*() does not refer to a joinable thread.
I am having trouble finding the exact wording that says a detached thread is not joinable, but I am pretty sure it is true.
So, either call pthread_join or pthread_detach, but not both.
If you read the standards documentation for pthread_join and pthread_exit and related pages, the join suspends execution "until the target thread terminates", and the thread calling pthread_exit doesn't terminate until it's done calling pthread_exit, so what you're worried about can't be the problem.
You may have corrupted memory somewhere (as Nemo suggests), or called pthread_exit from a cleanup handler (as user315052 suggests), or something else. But it's not "a race condition between pthread_join() and pthread_exit()", unless you're on a buggy or non-compliant implementation.
There is insufficient information to fully diagnose your problem. I concur with the other posted answers that the problem is more likely undefined behavior in your code than a race condition between pthread_join and pthread_exit. But I would also agree the existence of such a race would constitute a bug in the pthread library implementation.
Regarding pthread_join:
return_val = pthread_create(&_threadId, &attr,
(void *(*)(void *))initialize,
(void *)this);
//...
pthread_join(_threadId, NULL); // SEGV in here!!!
It looks like the join is in a class. This opens up the possibility that the object could be deleted while main is trying to do the join. If pthread_join is accessing freed memory, the result is undefined behavior. I am leaning towards this possibility, since accessing freed memory is very often undetected.
Regarding pthread_exit: The man page on Linux, and the POSIX spec state:
An implicit call to pthread_exit() is made when a thread other than the thread in which main() was first invoked returns from the start routine that was used to create it. The function's return value shall serve as the thread's exit status.
The behavior of pthread_exit() is undefined if called from a cancellation cleanup handler or destructor function that was invoked as a result of either an implicit or explicit call to pthread_exit().
If the pthread_exit call is made in a cleanup handler, you will have undefined behavior.
I'm reading the documentation about _beginthreadex and _endthreadex but there are a few things I don't understand.
Note that the documentation keeps documenting the "extended" and normal functions at the same time, but I'm not using _beginthread and _endthread; only their extended versions.
You can call _endthread or
_endthreadex explicitly to terminate a thread; however, _endthread or
_endthreadex is called automatically when the thread returns from the
routine passed as a parameter.
Terminating a thread with a call to
endthread or _endthreadex helps to
ensure proper recovery of resources
allocated for the thread.
If _endthreadex is called automatically, how come calling it helps to ensure "proper recovery of resources"? It shouldn't make any difference whether I call it or not, or does it?
_endthread automatically closes the thread handle (whereas _endthreadex
does not). Therefore, when using
_beginthread and _endthread, do not explicitly close the thread handle by
calling the Win32 CloseHandle API.
If _endthreadex does not close the handle, how come I shouldn't close it with CloseHandle?
All of my threads only voluntarily terminate by returning from their main function and are never forcefully terminated. According to the documentation, when this happens _endthreadex is called automatically.
This though won't close the handle. Assuming that I do need to close it, notwithstanding with what is said above, how can I do that since at this point the thread is dead? Should I somehow close it from another thread? What happens if I leave it open?
If _endthreadex is called automatically, how come calling it helps to ensure "proper recovery of resources"? It shouldn't make any difference whether I call it or not, or does it?
I think they meant this for the cases when you do not use a standard way of terminating your thread.
If _endthreadex does not close the
handle, how come I shouldn't close it
with CloseHandle?
You should close it with CloseHandle when using _endthreadex. The documentation says that only _endthread closes the handle (and therefore a CloseHandle call is superfluous).
All of my threads only voluntarily
terminate by returning from their main
function and are never forcefully
terminated. According to the
documentation, when this happens
_endthreadex is called automatically.
Closing the thread handles from the thread that started it is a commonly-used solution. You should remember the handle and in appropriate place wait for the thread to finish (using WaitForSingleObject) and then close its handle. If you don't do that you will cause a leak of resources. That is usually not a big problem if you have a few threads but it is definitely not good practice.
Don't call _endthread or _endthreadex unless you want to quickly and abnormally terminate the thread. While the CRT will free its own per thread data, none of the C++ destructors for any of the thread's objects will be called. It behaves similarly to how _exit ends the process without calling destructors.
The normal means of ending a thread should be by returning from the function passed as an argument to _beginthread or _beginthreadex. This will result in C++ destructors being called as a normal part of the function return.
ref:https://stackoverflow.com/a/31257350/6364089