Next: Tracing, Up: Sample Sessions [Contents][Index]
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.
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: Tracing, Up: Sample Sessions [Contents][Index]