Behavior of C++ const static after program termination - c++

I have a program which creates a thread (I am using C++ Boost library for creating threads) when started. In the main program I have registered my cleanup function as.
atexit(cleanExit)
// Trap some signals for a clean exit.
signal(SIGQUIT, signalled)
signal(SIGABRT, signalled)
signal(SIGTERM, signalled)
signal(SIGINT, signalled)
static void signalled(int signal)
{
exit(signal)
}
static void cleanExit(void)
{
thread->interrupt();
thread->join();
}
As you can see above during the clean exit process I interrupt the thread and then wait here (in the main process) so that the thread does its clean up stuff. When I call thread->interrupt, my thread gets interrupted and I do the thread cleanUp stuff. Till here everything is working smooth and there is no problem.
But the problem comes in when I call the cleanup function in the thread. In the cleanup function I am sending some status back to a server, for that I have created a utility function, In this utility function I am accessing a "const static string" member of the class. The problem is when I access this const static string my application got just stuck. I have checked with strace and I am getting a Seg Fault. But when I change this "const static string" to "const string" my cleanup goes smooth.
QUESTION
What is the behavior of C++ "const static" once the program is terminated. Do they giveup when exit is called (which can be seen in above case) or any thoughts on this behavior.
UPDATE # 1
Here is the thread handler function. As I have mentioned above its a Boost thread.
try {
while ( true ) {
// Do your job here.
// 1: We can be interrupted.
boost::this_thread::interruption_point();
}
}
catch (boost::thread_interrupted const& )
{
// Before exiting we need to process all request messages in the queue
completeAllWorkBeforeExiting();
}
When the main program calls thread->interrupt, the thread will raise thread_interrupted exception at # 1, and catching this exception I am doing my cleanup stuff.

const does not affect when any object is destroyed.
static objects are destroyed in the order opposite to their order of creation. atexit essentially creates an anonymous static object with the given function as its destructor. That is, static object destructors and atexit callbacks occur in the order opposite their construction/registration.
It's completely unsafe to call exit from a signal handler. All the signal handler is practically allowed to do is set a flag which is later polled by the threads. As you've mentioned, the signal handler runs at interrupt time, so it might interrupt a system call. It might interrupt malloc in such a way that bypasses malloc's multithreading locks, since the reentrancy is on the same thread, not a different one as usually happens.
So that's a source of all sorts of unpredictable behavior. Without seeing more, I can't be more specific about what effect static is having, but it probably has something to do with changing the object's lifetime and/or instantiating it once per object.

Related

Can std::threads be created / destroyed from global variables in a Windows DLL?

I'm creating a logging object which performs the real file writing work on a separate std::thread, and offers an interface to a log command buffer, syncing the caller threads and the one worker thread. Access to the buffer is protected by a mutex, there's an atomic bool for the worker thread exit condition, and I'm using Windows native Events as a signal to wake up the worker thread when new commands arrive. The object's constructor spawns the worker thread so it is immediately available. The worker thread is simply a while loop checking the exit condition, with in the loop a blocking wait for the signal. The object's destructor finally just sets the exit condition, signals the thread to wake up and joins it to ensure it's down before the object is fully destroyed.
Seems simple enough, and when using such an object somewhere in a function it works nicely. However, when declaring such an object as a global variable to have it usable for everyone it stops working. I'm on Windows, using Visual Studio 2017 with the 2015 tool chain. My project is a DLL plugin for another application.
The things I tried so far:
Start the thread in the constructor of the global object. This however makes the main thread hang immediately when my DLL is loaded. Pausing the app in the debugger reveals we're in the std lib, at a point where the main thread should have launched the worker thread and is now stuck waiting for a condition variable, presumably one that is signaled by the worker thread once it is launched?
Delay-construct the thread on demand when we first use the global object from somewhere else. This way constructing it goes nicely without a hang. However, when signalling the worker thread to exit from the destructor, the signal is sent, but the join on the worker thread now hangs. Pausing the app in the debugger reveals our main thread is the only one still alive, and the worker thread is already gone? A breakpoint placed in the worker thread function right before the close brace reveals it is never hit; the thread must be getting killed?
I also tried to start the thread via a std::future, starting it up async, and that one launches perfectly fine from the constructor in global objects. However, when the future tries to join the thread in the destructor, it hangs as well; here again no worker thread to be detected anymore while no breakpoint gets hit in it.
What could be going on? I can't imagine it's because the thread construction and destruction takes place outside main() so to speak; these std primitives should really be available at such moments, right? Or is this Windows specific and is the code running in the context of DllMain's DLL_PROCESS_ATTACH / DLL_THREAD_ATTACH events, where starting up threads might wreak havoc due to thread local storage not yet being up and running or such? (would it?)
EDIT -- added code sample
The following is an abbreviation/simplification of my code; it probably doesn't even compile but it gets the point across I hope :)
class LogWriter {
public:
LogWriter() :
m_mayLive(true) {
m_writerThread = std::thread(&C_LogWriter::HandleLogWrites, this); // or in initializer list above, same result
};
~LogWriter() {
m_mayLive = false;
m_doSomething.signal();
if (m_writerThread.joinable()) {
m_writerThread.join();
}
};
void AddToLog(const std::string& line) { // multithreaded client facing interface
{
Locker locker; // Locker = own RAII locker class
Lock(locker); // using a mutex here behind the scenes
m_outstandingLines.push_back(line);
}
m_doSomething.signal();
}
private:
std::list<std::string> m_outstandingLines; // buffer between worker thread and the rest of the world
std::atomic<bool> m_mayLive; // worker thread exit signal
juce::WaitableEvent m_doSomething; // signal to wake up worker thread; no std -- we're using other libs as well
std::thread m_writerThread;
int HandleLogWrites() {
do {
m_doSomething.wait(); // wait for input; no busy loop please
C_Locker locker; // access our line buffer; auto-released at end of loop iteration
Lock(locker);
while (!m_outstandingLines.empty()) {
WriteLineToLog(m_outstandingLines.front());
m_outstandingLines.pop_front();
if (!m_outstandingLines.empty()) {
locker.Unlock(); // don't hog; give caller threads some room to add lines to the buffer in between
std::this_thread::sleep_for(std::chrono::milliseconds(10));
Lock(locker);
}
};
} while (m_mayLive); // atmoic bool; no need to mutex it
WriteLineToLog("LogWriter shut down"); // doesn't show in the logs; breakpoints here also aren't being hit
return 0;
}
void WriteLineToLog(const std::string& line) {
... fopen, fprintf the line, flush, close ...
}
void Lock(C_Locker& locker) {
static LocalLock lock; // LocalLock is similar to std::mutex, though we're using other libs here
locker.Lock(&lock);
}
};
class Logger {
public:
Logger();
~Logger();
void operator() (const char* text, ...) { // behave like printf
std::string newLine;
... vsnprintf -> std::string ...
m_writer.AddToLog(newLine);
}
private:
LogWriter m_writer;
};
extern Logger g_logger; // so everyone can use g_logger("x = %d\n", x);
// no need to make it a Meyer Singleton; we have no other global objects interfering
Since you're writing a DLL in C++, you have to understand how "globals" in DLL's work. The compiler sticks their initialization in DllMain, before anything else that you would do there. But there are some strict rules what you can do in DllMain, as it runs under loader lock. The short summary is that you can't call anything in another DLL because that DLL cannot be loaded while your DllMain is running. Calling CreateThread is definitely not allowed, not even if wrapped inside a std::thread::thread constructor.
The problem with the destructor is quite possibly because your DLL has exited (can't tell without code). The DLL unloads before the EXE, and their respective globals are also cleaned up in that order. Any attempt to log from a destructor in an EXE will fail for obvious reasons.
There is no simple solution here. Andrei Alexandrescu's "Modern C++ Design" has a reasonable solution for logging in the non-DLL case, but you'll need to harden that for use in a DLL. An alternative is to check in your logging functions if your logger still exists. You can use a named mutex for that. If your log function fails in OpenMutex, then either the logger does not exist yet or it no longer exists.
Think I've encountered that destruction issue with DLLs to use with Unity.
The only solution I found back then was to essentially give up true global variables that would need cleanup.
Instead I put them in a separate class which is instantiated only a single time into a global pointer by some custom launch function. Then my DLL got a "quit()" function also called by the user of the DLL. The quit function correctly destroys the instance carrying the global variables.
Probably not the smoothest solution and you have a pointer-indirection on every access to the global variables, but it turned out to be comfortable for serializing the state of the global variables as well.

Interupt boost thread that is already in condition variable wait call

I'm using the boost interprocess library to create server and client programs for passing opencv mat objects around in shared memory. Each server and client process has two boost threads which are members of a boost::thread_group. One handles command line IO while the other manages data processing. Shared memory access is synchronized using boost::interprocess condition_variables.
Since this program involves shared memory, I need to do some manual cleaning before exiting. My problem is that if the server terminates prematurely, then the processing thread on the client blocks at the wait() call since the server is responsible for sending notifications. I need to somehow interrupt the thread stuck at wait() to initiate shared memory destruction. I understand that calling interrupt() (in my case, thread_group.interrupt_all()) on the thread will cause theboost::thread_interrupted exception to be thrown upon reaching a interruption point (such as wait()), which if left unhandled, would allow the shared memory destruction to proceed. However, when I try to interrupt the thread while it is in wait(), nothing seems to happen. For instance, this prints nothing to the command line:
try {
shared_mat_header->new_data_condition.wait(lock);
} catch (...) {
std::cout << "Thread interrupt occurred\n";
}
I am not at all sure, but it seems like the interrupt() call needs to occur before the thread enters wait() for the exception to be thrown. Is this true? If not, then what is the proper way to interrupt a boost thread that is blocked by a condition_variable.wait() call?
Thanks for any insight.
Edit
I accepted Chris Desjardins' answer, which does not answer the question directly, but has the intended effect. Here I'm translating his code snippet for use with boost::interprocess condition variables, which have slightly different syntax than boost::thread condition variables:
while (_running) {
boost::system_time timeout = boost::get_system_time() + boost::posix_time::milliseconds(1);
if (shared_mat_header->new_data_condition.timed_wait(lock, timeout))
{
//process data
}
}
I prefer to wait with timeouts, then check the return code of the wait call to see if it timed out or not. In fact I have a thread pattern I like to use that resolves this situation (and other common problems with threads in c++).
http://blog.chrisd.info/how-to-run-threads/
The main point for you is to not block infinitely in a thread, so your thread would look like this:
while (_running == true)
{
if (shared_mat_header->new_data_condition.wait_for(lock, boost::chrono::milliseconds(1)) == boost::cv_status::no_timeout)
{
// process data
}
}
Then in your destructor you set _running = false; and join the thread(s).
Try using the "notify function". Keep a pointer to your condition variable and call that instead of interrupting the threads. Interrupting is much more costly than a notify call.
So instead of doing
thread_group.interrupt_all()
call this instead
new_data_condition_pointer->notify_one()

C++ Multithreading - When does a child thread exit?

I create a thread to whom a void* to a structure is passed as argument. This structure is created in a class. When this class destructor is called, that is at the end of main, the structure is deleted. So later i see the child thread is launched again, and referring to its void* argument throws an exception as its already deallocated. I was hoping that the child threads gets exited before the destructors are called but that's not happening.
From Exitthread page in MSDN,
However, in C++ code, the thread is
exited before any destructors can be
called or any other automatic cleanup
can be performed.
whats the destructors the above line is referring to?
The child thread executes on a procedure that has a lifetime of the main thread. Using a global flag, i thought i could control the child thread execution. I set the global flag on the last routine that main thread executes. But does global objects get deallocated before the termination of child thread. In that case, even that wont help me.
To summarise, whats the best way i could exit a child thread which has the lifetime of the main thread? I do not want to use terminatethread api.
Edit: Some code sample
//In a method at end of main
void EndofMain()
{
WaitForSingleObject(globalObj->hMutex, INFINITE)
globalObj->threadActive = false;
ReleaseMutex(globalObj->hMutex);
}
void ChildThreadProc(void* data)
{
while(globalObj->threadActive)
{
WaitForSingleObject(globalObj->hMutex, INFINITE)
//do other stuff
ReleaseMutex(globalObj->hMutex);
sleep(1000);
}
}
Now is there a chance where globalObj is deallocated and then the child thread is called?
One option would be to have the main thread signal the child thread that it should exit (perhaps by setting a Boolean flag), then using WaitForSingleObject at the end of main() to wait for the thread to terminate before returning and calling the destructors. This prevents the error you've described by forcing the thread to exit (in a safe manner) before destructors fire.

Do threads clean-up after themselves in Win32/MFC and POSIX?

I am working on a multithreaded program using C++ and Boost. I am using a helper thread to eagerly initialize a resource asynchronously. If I detach the thread and all references to the thread go out of scope, have I leaked any resources? Or does the thread clean-up after itself (i.e. it's stack and any other system resources needed for the itself)?
From what I can see in the docs (and what I recall from pthreads 8 years ago), there's not explicit "destory thread" call that needs to be made.
I would like the thread to execute asynchronously and when it comes time to use the resource, I will check if an error has occured. The rough bit of code would look something like:
//Assume this won't get called frequently enough that next_resource won't get promoted
//before the thread finishes.
PromoteResource() {
current_resource_ptr = next_resource_ptr;
next_resource_ptr.reset(new Resource());
callable = bind(Resource::Initialize, next_resource); //not correct syntax, but I hope it's clear
boost::thread t(callable);
t.start();
}
Of course--I understand that normal memory-handling problems still exist (forget to delete, bad exception handling, etc)... I just need confirmation that the thread itself isn't a "leak".
Edit: A point of clarification, I want to make sure this isn't technically a leak:
void Run() {
sleep(10 seconds);
}
void DoSomething(...) {
thread t(Run);
t.run();
} //thread detaches, will clean itself up--the thread itself isn't a 'leak'?
I'm fairly certain everything is cleaned up after 10 seconds-ish, but I want to be absolutely certain.
The thread's stack gets cleaned up when it exits, but not anything else. This means that anything it allocated on the heap or anywhere else (in pre-existing data structures, for example) will get left when it quits.
Additionally any OS-level objects (file handle, socket etc) will be left lying around (unless you're using a wrapper object which closes them in its destructor).
But programs which frequently create / destroy threads should probably mostly free everything that they allocate in the same thread as it's the only way of keeping the programmer sane.
If I'm not mistaken, on Windows Xp all resources used by a process will be released when the process terminates, but that isn't true for threads.
Yes, the resources are automatically released upon thread termination. This is a perfectly normal and acceptable thing to do to have a background thread.
To clean up after a thread you must either join it, or detach it (in which case you can no longer join it).
Here's a quote from the boost thread docs that somewhat explains that (but not exactly).
When the boost::thread object that
represents a thread of execution is
destroyed the thread becomes detached.
Once a thread is detached, it will
continue executing until the
invocation of the function or callable
object supplied on construction has
completed, or the program is
terminated. A thread can also be
detached by explicitly invoking the
detach() member function on the
boost::thread object. In this case,
the boost::thread object ceases to
represent the now-detached thread, and
instead represents Not-a-Thread.
In order to wait for a thread of
execution to finish, the join() or
timed_join() member functions of the
boost::thread object must be used.
join() will block the calling thread
until the thread represented by the
boost::thread object has completed. If
the thread of execution represented by
the boost::thread object has already
completed, or the boost::thread object
represents Not-a-Thread, then join()
returns immediately. timed_join() is
similar, except that a call to
timed_join() will also return if the
thread being waited for does not
complete when the specified time has
elapsed.
In Win32, as soon as the thread's main function, called ThreadProc in the documentation, finishes, the thread is cleaned up. Any resources allocated by you inside the ThreadProc you'll need to clean up explicitly, of course.

What is the difference between exit() and abort()?

In C and C++, what is the difference between exit() and abort()? I am trying to end my program after an error (not an exception).
abort() exits your program without calling functions registered using atexit() first, and without calling objects' destructors first. exit() does both before exiting your program. It does not call destructors for automatic objects though. So
A a;
void test() {
static A b;
A c;
exit(0);
}
Will destruct a and b properly, but will not call destructors of c. abort() wouldn't call destructors of neither objects. As this is unfortunate, the C++ Standard describes an alternative mechanism which ensures properly termination:
Objects with automatic storage duration are all destroyed in a program whose function main() contains no automatic objects and executes the call to exit(). Control can be transferred directly to such a main() by throwing an exception that is caught in main().
struct exit_exception {
int c;
exit_exception(int c):c(c) { }
};
int main() {
try {
// put all code in here
} catch(exit_exception& e) {
exit(e.c);
}
}
Instead of calling exit(), arrange that code throw exit_exception(exit_code); instead.
abort sends a SIGABRT signal, exit just closes the application performing normal cleanup.
You can handle an abort signal however you want, but the default behavior is to close the application as well with an error code.
abort will not perform object destruction of your static and global members, but exit will.
Of course though when the application is completely closed the operating system will free up any unfreed memory and other resources.
In both abort and exit program termination (assuming you didn't override the default behavior), the return code will be returned to the parent process that started your application.
See the following example:
SomeClassType someobject;
void myProgramIsTerminating1(void)
{
cout<<"exit function 1"<<endl;
}
void myProgramIsTerminating2(void)
{
cout<<"exit function 2"<<endl;
}
int main(int argc, char**argv)
{
atexit (myProgramIsTerminating1);
atexit (myProgramIsTerminating2);
//abort();
return 0;
}
Comments:
If abort is uncommented: nothing is printed and the destructor of someobject will not be called.
If abort is commented like above: someobject destructor will be called you will get the following output:
exit function 2
exit function 1
The following things happen when a program calls exit():
Functions registered by the atexit function are executed
All open streams are flushed and closed, files created by tmpfile are removed
The program terminates with the specified exit code to the host
The abort() function sends the SIGABRT signal to the current process, if it is not caught the program is terminated with no guarantee that open streams are flushed/closed or that temporary files created via tmpfile are removed, atexit registered functions are not called, and a non-zero exit status is returned to the host.
From the exit() manual page:
The exit() function causes normal process termination and the value of
status & 0377 is returned to the parent.
From the abort() manual page:
The abort() first unblocks the SIGABRT signal, and then raises that
signal for the calling process. This results in the abnormal termination of the process unless the SIGABRT signal is caught and the signal
handler does not return.
abort sends the SIGABRT signal. abort does not return to the caller. The default handler for the SIGABRT signal closes the application. stdio file streams are flushed, then closed. Destructors for C++ class instances are not, however (not sure on this one -- perhaps results are undefined?).
exit has its own callbacks, set with atexit. If callbacks are specified (or only one), they are called in the order reverse of their registration order (like a stack), then the program exits. As with abort, exit does not return to the caller. stdio file streams are flushed, then closed. Also, destructors for C++ class instances are called.