A new start

OK, so this blog kind of died. But hey, lets give it another go. I think I may have been a bit to ambitious the last time around. So this time, I will be aiming for smaller posts, more frequent, and as the new title suggests, focused on C++.

For the last year or so I have mainly been playing around with java. Both for play(android) and at work. But 2015 looks to be a year focused on C++ for me, so I figured its a good time to brush up on all the things that have happened out there in C++ land. At work our project will move to a more recent Intel compiler, which should support more of the more recent changes in the language. And of course, new versions of GNU compilers are out, so there is more to play with on my laptop as well.

My goal is to learn a new thing every day or so, and share my discoveries here. Hopefully there will be something to share on a semi-daily basis. Some of the topics I hope to learn more about:

  • Unit testing tools and techniques
    Currently I am using googletest and googlemock, but perhaps there are other/better things to consider
  • Modern C++ idioms
    C++11 and C++14 enables a quite different coding style, hopefully it will reduce the amount/severity of bugs and make the code cleaner
  • Qt
    Its a few years since I last did serious work using Qt. I’m particularly keen to see how easy it is to write android apps using Qt.
  • Boost
    I am now in the habit of always checking if there is already a solution for my problem in a boost library. However, there are still lots and lots of boost libraries I have not used.

A few words about the project I am working on. The codebase is a legacy system, with the most ancient components written in fortran in the 1970s. Fortunately the parts I am interfacing with is fairly modern C++. Some boost libraries are used, but as the code was written before we had any compilers supporting C++ 11, it does not use any of the new language features. There are unit tests, mostly using GoogleTest and GoogleMock  as test frameworks. However, they are often to few, and not well maintained.

As for private project I will probably start of by trying to get a Qt hello world app up and running on my mobile phone, and then take it from there.

 

 

 

 

Advertisement

pthread_cancel considered harmful

Now, time and again someone will come up with a problem which they think they can solve using pthread_cancel, and every time I have tried to discourage it. So the context is usually some C++ application, in some cases it is fairly well designed and in other cases it has been a mess. But no matter what, there is no way to make this work in a way that won’t either cause them to make huge changes to their application that they really do not want to make, or that their application will crash from time to time when it is about to process the cancellation.

The problem lies with how pthread_cancel interacts with some other features of C++, specifically exception handling. Consider the following code:

#include <unistd.h>
#include <pthread.h>
#include <iostream>
using namespace std;
struct Sleepy
{
  ~Sleepy()
  {
    cerr<<"...zZzZz..."<<endl;
    sleep(999);
  }
};
 
void* sleepyThread(void*)
{
  try 
  {        
    Sleepy f;
    cerr<<"Fall asleep...\n";
    throw string("WAKE UP!!");
  } catch(string& e)
  {
    cerr<<"Caught exception:"<<e<<endl;
  }    
}

int main()
{
  pthread_t thread;
  int id=pthread_create(&thread,NULL,&sleepyThread,NULL);
  sleep(1); //Give the new thread time to get to the sleeping part...
  cerr<<"lets try to cancel it..."<<endl;
  pthread_cancel(thread);
  pthread_join(thread,NULL);
  cerr<<"All is done now..."<<endl;
}

Most likely, if you compile this using a recent compiler, you will end up with something like this:

Fall asleep...
...zZzZz...
lets try to cancel it...
terminate called without an active exception
Aborted

What happens here is that the thread is throwing an exception, and during stack unwinding it call the desctructor of the Sleepy object. We all know that we are not supposed to throw exceptions inside destructors, because a destructor is likely to be called while processing an exception, and 2 exceptions being called at the same time causes the C++ runtime to abort.

“But there is no exception being thrown here!!”, I hear you say. Well, not true. The sleep function inside the destructor is a cancellation point, and when pthread_cancel is called, what actually happens is that an anonymous exception is thrown to do the stack unwinding. Oh dear 🙂

Now this is a problem whenever you want to use one of the system calls that also act as a cancellation points inside a destructor. unfortunately, there are a lot of these system calls that, and some of them you really do want to call in a destructor. Wouldn’t you want to call close(), fclose(), dirclose()?This is certainly going to mess with your design, RAII classes are out the window for some commn cases…what else will have to follow to make it cancellation safe?

There are probably be simple cases where cancellation will work as expected, but as soon as you start doing more complex work inside a thread, chances are that you will end up aborting your entire process instead of cancelling one thread. The fun part is that unless you take special care like I did in the example to avoid race-conditions it will work as expected 9999 out of 10000 times. But just that one time when you are running a demo in front of your CEO, the close() will happen just as you cancel, and boooooom……

So what is the solution then. Well, for sure, if aborting your threads is important, you need to design for it. My bet is that something like boosts ineruptible threads are more what you really need than pthread_cancel..

This is me

So, just a few words about me in my first post…

I’m a developer, mainly working with huge,internal, C++  projects on UNIX/Linux. I have been doing this for the last 10 years or so, which have generally been fun. Sometimes I have been working on huge SUN servers, other times on embedded linux. I have written GUIs in everything from raw Xlib  to Qt(the latter is rather enjoyable actually….).

Of course, I have touched in on other technologies as well. I enjoy picking up perl now and again and doing something clever with it. Its satisfying how much you can get done in very little time. Of course, maintaining it often a bit hard, but I have found that with decent comments, proper classes and making sure its all under VC it can be done….

If I am forced to it(or gently asked by my boss), I will make some fixes or updates to java applications, and as I have been a sysadmin before, I tend to use shell scripts now and again as well. For reasons best forgotten, I have also done my share of tcl and Fortran programming….

My preferred IDE is emacs, but I am not religious about it, and for a quick edit I’ll easily use vi. If someone hands me a windows box, I will rather install emacs than touch notepad.exe:-)

I have a bit of an interest in VC systems, and I hope to soon start using git for something beyond keeping my homedirectory in order. At work we have a home-made VC and build systems, which I have been the local superuser for. Its an interesting bit of technology, and when it was made was quite  ahead of its time. However, DVCS is a paradigm shift, and there are a lot of interesting things that can be done with git and similar systems that can’t be done with our homegrown system, and I really look forward to start experimenting with those…

OK, thats it for now…I’m sure I’ll write more later, but for now I would rather get on to my second post, which is about a topic that seems to come up now and again….