Next: , Up: Sample Sessions   [Contents][Index]


1.1.1 How not to debug your Makefile

Before we get into debugging proper, we’ll discuss tracing and a pitfall the author once made in his first attempt to debug a large and mysterious Makefile. Chances you may have happened to you too.

A simplified form of debugging is tracing. Often this may be good enough to understand what might have gone wrong. In fact, in the Unix shell world (tcsh, csh, bash, sh) prior to my debugger for bash (http://bashdb.sourceforge.net) tracing along with print statements was about all that was available to debug a program.

GNU Make has had for a long time a “debug” flag (--debug or -d) which prints “lots of debugging information.” For the unwary one might think you just add this simple option and that’s going to do what you want. Wrong!1

Alas, the --debug option gives way too much information to be helpful. Furthermore, debug-flag information omits information that would be helpful.

To elaborate upon this, here is a simple small Makefile with an invalid shell command in it:

1: # Makefile to show off tracing
2: .PHONY: all
3: all: foo
4:
5: foo:
6: 	@case $(MAKE) in \
7: 	*/remake|remake) echo "Enlightened!";; \
8: 	*/make|make) echo "This is what most folks use.";; \
9: 	esac
10: 	@bogus-command

But now let’s see what happens when we run “debug” from an unpatched GNU Make:

$ /usr/bin/make -d -f test1.mk
Copyright (C) 2006  Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.

This program built for i486-pc-linux-gnu
Reading makefiles...
Reading makefile `test1.mk'...
Updating makefiles....
 Considering target file `test1.mk'.
  Looking for an implicit rule for `test1.mk'.
  Trying pattern rule with stem `test1.mk'.
  Trying implicit prerequisite `test1.mk.o'.
  Trying pattern rule with stem `test1.mk'.
  Trying implicit prerequisite `test1.mk.c'.

... over 350 lines later ...

 No need to remake target `test1.mk'.
Updating goal targets....
Considering target file `all'.
 File `all' does not exist.
  Considering target file `foo'.
   File `foo' does not exist.
   Finished prerequisites of target file `foo'.
  Must remake target `foo'.
Putting child 0x08acced8 (foo) PID 307 on the chain.
Live child 0x08acced8 (foo) PID 307
This is what most folks use.
Got a SIGCHLD; 1 unreaped children.
Putting child 0x095b1310 (foo) PID 13440 on the chain.
Live child 0x095b1310 (foo) PID 13440
Reaping winning child 0x095b1310 PID 13440
make: bogus-command: Command not found
Got a SIGCHLD; 1 unreaped children.
Live child 0x095b1310 (foo) PID 13441
Reaping losing child 0x095b1310 PID 13441
make: *** [foo] Error 127
Removing child 0x095b1310 PID 13441 from chain.

The output would have been about twice as long were it not for the fact that we declared all a “phony” target!

Clearly this information referring to rule stems, implicit prerequisites, SIGCHLD, pids, and unreaped children is intended for someone who is well versed with the internals of GNU Make.

But even for someone such as myself who has become more knowledgeable (through writing this debugger), it still isn’t all that helpful. In the midst of the above jumble, the program reports:

make: bogus-command: command not found

Say what? Okay, but where in the source Makefile did that come from? Since we added the debug output we see “foo” listed beforehand after skipping hundreds of lines, but in a normal make, there would have been no mention of “foo.” In our simple example tracking down the location is easy. But when you have a Makefile which is hundreds of lines long as any Makefile is when it is generated from automake, it would be nice to list the line in the Makefile and full filename as well as the target name.


Footnotes

(1)

From the standpoint of a nice user interface, this options should get replaced with --trace. At present, this change is probably a little to young to to make such a bold change, tempting as it is to do.


Next: , Up: Sample Sessions   [Contents][Index]