A Touching Story

        Submitter: Oleg Goldshmidt

        Language: make

        Date:        2004/06/05

A few days ago a couple of colleagues came to me and asked for help with a really strange phenomenon. They have a C++ program that consists of a few files that they link with a number of libraries. The problem is that when they run the program it gets stuck - just hangs at some point. The weird part of it is that when they touch(1) the file that contains the main(), say prog.cc, build the application (using GNU make(1), of course) again, and re-run, the program works and terminates normally. 

Well, first of all I of course reproduced the effect successfully. I also ran the program in the debugger, killed it when it hung, and looked at the stack backtrace. Looks like they had a deadlock somewhere. But what's with this touch(1) business?

Let's look at the Makefile. Looks simple enough, and actually quite decent. The main target is built with the equivalent of

$(PROG):	prog.o foo.o bar.o
$(CXX) -o $@ $? $(LDFLAGS) $(LIBS)

Oh, well, now it is clear: a quick change of $? to $^ did not fix the deadlock problem, but restored the sanity of everybody involved: it turned out that the application worked even without foo.o or bar.o, and the latter only introduced additional mutithreaded stuff with buggy synchronization. 

In case you still have not got the picture: with GNU make(1) $? stands for the newly updated prerequisites only, so after touch prog.cc only prog.o, but not foo.o or bar.o were linked into the executable. $^ stands for all the prerequisites.

Fixing the deadlock was left as an exercise.