[Top] | [Contents] | [Index] | [ ? ] |
This file describes the GNU Make debugger
This is the 3.81+dbg-0.2 Edition, January 2009
Copyright (C) 2004, 2005, 2006, 2007, 2009 Rocky Bernstein
1. Summary of the GNU Make Debugger | Overview of Debugger with a sample session | |
2. Getting in and out and new GNU Remake Command Options | Getting in and out and GNU Make command options | |
3. GNU Remake Debugger Command Reference | the GNU Make debugger command reference | |
4. Using the GNU Make debugger from a front-end user interface | ||
5. Reporting Bugs | Reporting bugs | |
6. History and Acknowledgments | ||
Indexes (nodes containing large menus) | ||
Command Index | An item for each command name. | |
General Index | An item for each concept. |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The purpose of a debugger such as the GNU Make debugger is to allow you to see what is going on “inside” the GNU Make debugger when it processes a Makefile.
The GNU Remake debugger can do four main kinds of things (plus other things in support of these) to help you catch bugs in the act:
Although you can use the the GNU Make debugger to debug Makefiles, it can also be used just as a front-end for learning more about Makefiles and writing them with GNU Remake.
A degenerate and less-interactive form of debugging is tracing in which one passively watches some of the steps that go on in processing a Makefile.
1.1 Sample GNU Remake Debugger Sessions | Sample GNU Make Debugger sessions | |
Free software | Freely redistributable software |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
You can use this manual at your leisure to read all about the GNU Make debugger. However, a handful of commands are enough to get started using the debugger. This chapter illustrates those commands.
1.1.1 How NOT to debug GNU Make | How NOT to debug your program | |
1.1.2 Sample GNU Remake Trace Sessions | Using –trace or -x on a simple example | |
1.1.3 Tracing Makefile Reading | A real-world trace. | |
1.1.4 Simple GNU Remake Debug Sessions | Getting into the Debugger (–debugging) | |
1.1.5 Debugging Variables | ||
1.1.6 Debugging Commands |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [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 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:
!: # Makefile to show off tracing 2: .PHONY: all 3: all: foo 4: 5: foo: 6: @case $(MAKE) in \ 7: */remake|remake) echo "Enlightended!";; \ 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) 2002 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. 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'. 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 |
?? 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.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Okay so now that we know what not to do, lets delve into things may be more helpful.
There are variants of the --debug
command option that provide
shorter and more-interesting information. One is called “basic”
tracing. Another is the --just-print
option.
Again here's the sample Makefile:
!: # Makefile to show off tracing 2: .PHONY: all 3: all: foo 4: 5: foo: 6: @case $(MAKE) in \ 7: */remake|remake) echo "Enlightended!";; \ 8: */make|make) echo "This is what most folks use.";; \ 9: esac 10: @bogus-command |
In an unpatched GNU Make version 3.81 (and earlier) GNU Make,
--just-print
gives this:
$ make --just-print -f test1.mk case make in \ */remake|remake) echo "Enlightended!";; \ */make|make) echo "This is what most folks use.";; \ esac This is what most folks use. bogus-command |
Well, not much different from the original Makefile, except that information about where this gets run from is curiously missing. If there had been several targets that had commands, from the output it would not be possible to determine which command was associated with which target.
One of the goals of GNU Remake is to include reference information. Here's what we give instead:
$ make --just-print -f test.mk1 ##>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> /tmp/test1.mk:6: foo case /tmp/remake/src/./make in \ */remake|remake) echo "Enlightended!";; \ */make|make) echo "This is what most folks use.";; \ esac ##<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< This is what most folks use. ##>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> /tmp/test1.mk:10: foo bogus-command ##<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< |
What's different is that we make more clear where in the file this
command is getting run from and from what target. This may be a little
bit subtle, but from the above output it is more apparent that there
are two separate commands(2) that are getting run
from target foo
: one at line 6 and another at line 10.
One last and perhaps also subtle point is the format of the location
information. This format is similar to other debugger output. The
above command is run inside a GNU Emacs compilation buffer the format
of the message is such that compile-goto-error
will possition
one at that point in the file in another Emacs window.
Now let's try --debug=basic
alluded to at the beginning of this
section. In an unpatched GNU Make version 3.81 (and earlier)
GNU Make --debug=basic
gives this:
$ make --debug=basic -f test1.mk GNU Make 3.80 Copyright (C) 2002 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. Reading makefiles... Updating goal targets.... File `all' does not exist. File `foo' does not exist. Must remake target `foo'. This is what most folks use. make: bogus-command: Command not found make: *** [foo] Error 127 ########################################################## |
The --debug=basic
command-line switch also works in
GNU Remake as well if that's all you want.(3)
Now let's try the new kind of trace we provide in this patched
GNU Remake. We use the new option --trace
which has the
short-form option format -x
.
And here's the trace of it:
$ remake --trace -f test1.mk Reading makefiles... Updating goal targets.... /tmp/test1.mk:3 File `all' does not exist. /tmp/test1.mk:5 File `foo' does not exist. /tmp/test1.mk:5 Must remake target `foo'. ##>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> /tmp/test1.mk:6: foo case /tmp/remake/src/./make in \ */remake|remake) echo "Enlightended!";; \ */make|make) echo "This is what most folks use.";; \ esac ##<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + case /tmp/remake/src/./make in + echo 'This is what most folks use.' This is what most folks use. ##>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> /tmp/remake/src/test1.mk:10: foo bogus-command ##<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + bogus-command /bin/sh: bogus-command: command not found test1.mk:10: *** [foo] Error 127 #0 foo at /tmp/test1.mk:10 #1 all at /tmp/test1.mk:3 Command-line arguments: "--trace -f test1.mk" |
So in some ways this is just a combination of the enhanced (with
location information) --just-print
option combined with the
enhanced --debug=basic
information.
What is completely new and hasn't been seen above is the shell tracing
information and information given when we hit an error. After the
error and we report the return code (127), the stack of targets is
listed. We were working on target foo
on line 10 of file
/tmp/test1.mk
which was rebuilt because we were making target
all
on line 3 of file /tmp/test1.mk
.
In other words, when we hit the error, the above trace gives some idea of why we decided to to run line 10 and what got executed before that, what targets were in the process of getting considered at the error, and how the program was run.
One last subtlety that you might not have noticed is that we echoed
the command bogus-command
even though the original makefile had
this set to be silent (in particular by preceding that command with an
@). When tracing, we override any silent execution (making execution
more verbose); information is usually helpful in finding what's going
on and what got run.
In sum, I hope I've conveyed the idea that the goal is simple trace output for a simple Makefile. Although I think that the above may be improved, it is far better than what has previously been available in GNU make.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
GNU Make and GNU Remake work like many other interpreters. First Makefiles are read in and parsed and then they are “executed” which in GNU Make means that dependency checks are done and actions are performed based on those checks. However there is quite a bit work that may be done just in portion which reads in the Makefiles and performs variable expansion.
To see this, let's use a real example – the Makefile for the GNU Make + Debugger. For comparison, here is a simple trace:
$ remake --trace Reading makefiles... Updating goal targets.... /tmp/remake/src/Makefile:257 File `all' does not exist. /tmp/remake/src/Makefile:470 File `all-am' does not exist. /tmp/remake/src/Makefile:470 Must remake target `all-am'. Is a phony target. /tmp/remake/src/Makefile:470 Successfully remade target file `all-am'. /tmp/remake/src/Makefile:257 Must remake target `all'. Is a phony target. /tmp/remake/src/Makefile:257 Successfully remade target file `all'. remake: Nothing to be done for `all'. |
So far so good – still pretty simple output even though the Makefile
in this case is pretty complex, is hundreds of lines long and has
thousands of dependencies noted. Digging just a little into this
complexity, If we want to trace the files that were read in performing
the above, we can use the sub-option read
on the --trace
option:
$ remake --trace=read Makefile Reading makefiles... Reading makefile `Makefile'... /tmp/remake/src/Makefile:329 Reading makefile `.deps/alloca.Po' (search path) (no ~ expansion)... /tmp/remake/src/Makefile:330 Reading makefile `.deps/getloadavg.Po' (search path) (no ~ expansion)... ... about 32 more lines like the above ... Updating goal targets.... remake: `Makefile' is up to date. |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Now let's go into the debugger. To do this, use the --debugger
or -X
option. Again we'll use the Makefile from the source code
of this distribution.
$ remake --debugger Reading makefiles... (/tmp/src/remake/src/Makefile:263) Makefile.in: Makefile.am ../config/readline.m4 ../gettext.m4 ../iconv.m4 ../lib-ld.m4 ../lib-link.m4 ../lib-prefix.m4 ../progtest.m4 ../acinclude.m4 ../configure.ac ../aclocal.m4 mdb<0> |
Before the prompt mdb<0>
, we show the position in the file,
the target Makefile.in
, and the dependencies of this target
Makefile.am
, ..config/readline.m4
....
The “0” in the prompt mdb<0>
is the command history number
it increments as we enter commands.
Is this really the top-level target? The where
command,
(see Backtraces (‘where’)), shows you the target call stack:
mdb<0> where =>#0 Makefile.in at /tmp/src/remake/src/Makefile:263 #1 Makefile at /tmp/src/remake/src/Makefile:276 mdb<1> |
No, we were triggered by checking dependencies from
Makefile
.(4)
Notice that the prompt now lists “1” since we entered a command.
We can use the step
command, (Step (‘step’)), to progress a little
in the interpretation or execution of the makefile:
mdb<1> step (/tmp/src/remake/src/Makefile:290) ../aclocal.m4: ../config/readline.m4 ../gettext.m4 ../iconv.m4 ../lib-ld.m4 ../lib-link.m4 ../lib-prefix.m4 ../progtest.m4 ../acinclude.m4 ../configure.ac mdb<2> where =>#0 ../aclocal.m4 at /tmp/remake/src/Makefile:290 #1 Makefile.in at /tmp/remake/src/Makefile:263 #2 Makefile at /tmp/remake/src/Makefile:276 |
Before the prompt the debugger printed some information about the
target, namely its name and dependencies. However if you want the full
details about a target, one can use the target
(Examining Targets (‘target’)
command:
mdb<3> target ../aclocal.m4: ../config/readline.m4 ../gettext.m4 ../iconv.m4 ../lib-ld.m4 ../lib-link.m4 ../lib-prefix.m4 ../progtest.m4 ../acinclude.m4 ../configure.ac # Implicit rule search has not been done. # Implicit/static pattern stem: `' # Last modified 2005-12-10 21:41:10 # File has not been updated. # automatic # := ../aclocal.m4 # automatic # % := # automatic # * := # automatic # + := ../config/readline.m4 ../gettext.m4 ../iconv.m4 ../lib-ld.m4 ../lib-link.m4 ../lib-prefix.m4 ../progtest.m4 ../acinclude.m4 ../configure.ac # automatic # | := # automatic # < := ../config/readline.m4 # automatic # ^ := ../config/readline.m4 ../gettext.m4 ../iconv.m4 ../lib-ld.m4 ../lib-link.m4 ../lib-prefix.m4 ../progtest.m4 ../acinclude.m4 ../configure.ac # automatic # ? := # commands to execute (from `Makefile', line 291): cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh |
I could have gotten the same output explicitly giving a target name
such as target ../aclocal.m4
, or used the GNU Make
automatic variable name @
.
What is going on here is we are checking to see if the Makefile needs
to be remade, and in doing this we need to see if Makefile.in needs
to be remade and that depends on target ../aclocal.m4
.
We don't have to be stopped on a target to get information about it:
mdb<4> target all-am target all-am all-am: Makefile make loadavg ar_fns.h arscan.h commands.h dbg_break.h dbg_cmd.h dbg_fns.h dbg_stack.h debug.h default.h dep.h dir_fns.h expand.h file.h function.h gettext.h hash.h implicit.h job.h make.h misc.h print.h read.h remake.h remote-stub.h rule.h trace.h types.h variable.h vpath.h # Phony target (prerequisite of .PHONY). # Implicit rule search has not been done. # Implicit/static pattern stem: `' # File does not exist. # File has not been updated. # automatic # := all-am # automatic # % := # automatic # * := # automatic # + := Makefile make loadavg ar_fns.h arscan.h commands.h dbg_break.h dbg_cmd.h dbg_fns.h dbg_stack.h debug.h default.h dep.h dir_fns.h expand.h file.h function.h gettext.h hash.h implicit.h job.h make.h misc.h print.h read.h remake.h remote-stub.h rule.h trace.h types.h variable.h vpath.h # automatic # | := # automatic # < := all-am # automatic # ^ := Makefile make loadavg ar_fns.h arscan.h commands.h dbg_break.h dbg_cmd.h dbg_fns.h dbg_stack.h debug.h default.h dep.h dir_fns.h expand.h file.h function.h gettext.h hash.h implicit.h job.h make.h misc.h print.h read.h remake.h remote-stub.h rule.h trace.h types.h variable.h vpath.h # automatic # ? := mdb<5> |
However information may change depending on where Make is. In particular note that “Implicit rule search has not been done.”
If all of this is proceeding too slowly, could set a
breakpoint
on a target of interest, perhaps all-am
. Like
this:
mdb<4> restart Changing directory to /tmp/remake/src and restarting... Reading makefiles... /tmp/remake/src/Makefile:255: Makefile.in mdb<0> break all-am Breakpoint on target all-am set. |
The restart
command was used to restart execution since we've
already passed considering the "all-am" target. So let's
continue
, (Continue (‘continue’)), execution and see what happens:
mdb<1> continue Updating goal targets.... /tmp/remake/src/Makefile:250 File `all' does not exist. /tmp/remake/src/Makefile:461: all-am mdb<2> where =>#0 all-am at /tmp/src/remake/src/Makefile:472 #1 all at /tmp/src/remake/src/Makefile:259 |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
We've seen we can get information about GNU Remake's targets. We
can also get information about GNU Remake's variables. That is done
with the print
command. (See Print variable info (‘print’).)
mdb<4> print MAKE (origin default) MAKE = $(MAKE_COMMAND) |
The (origin default)
means this is a built-in
definition. There is another print which does full expansion
of the variables. So if I run x
(examine
) instead I get:
mdb<5> examine MAKE (origin default) MAKE := /tmp/remake/src/./make |
Note that in printing expanded values we use “:=” while non-expanded values we use “=”. This output matches the semantics of these assignment operators.
In fact, examine
doesn't need a variable name, it will work
with a string. So I could type “x This is $(MAKE)
” or
“x $(bin_PROGRAMS) $(noinst_PROGRAMS)
”. For the latter, I
get:
mdb<6> x $(bin_PROGRAMS) $(noinst_PROGRAMS) make loadavg |
No location identification is given here since what I put in isn't a variable.
But I can also change values too using either set
or
setq
. (See Setting a variable to an expanded string (‘set variable’) and Setting a variable to an unexpanded string (‘setq’).) Let's see the difference
between the two.
mdb<7> set MAKE $(MAKE_COMMAND) Variable MAKE now has value '/tmp/remake/src/./make' mdb<8> setq MAKE $(MAKE_COMMAND) Variable MAKE now has value '$(MAKE_COMMAND)' |
So with set
, the value in the expression $(MAKE_COMMAND)
is expanded before the variable definition is assigned. With
setq
, See section Setting a variable to an unexpanded string (‘setq’), the internal variables are kept
unexpanded. Which you use or want is up to you.
Note the irregular syntax of set
and "setq
. Don't put an
equal sign (=
) between the variable and the expression. That
is, set MAKE = $(MAKE_COMMAND)
" gives:
Variable MAKE now has value '= /tmp/remake/src/./make' |
which is probably not what you want. One may optionally put in the
the word "variable" when using set
, one must not supply
it with "setq." Down the line, someone (maybe you!) will
probably put in a command parser.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Now consider the following sample Makefile:
$ cat -n test2 1 PACKAGE=make 2 3 all: $(PACKAGE).txt 4 5 $(PACKAGE).txt: ../doc/mdb.texi 6 makeinfo --no-headers $< > $ |
$ remake -X -f test2 Reading makefiles... Updating goal targets.... /tmp/remake/src/test2:3 File `all' does not exist. (/tmp/remake/src/test2:3): all |
As before we'll use the target
command to show information about
all
:
mdb<0> target all: make.txt # Implicit rule search has not been done. # Implicit/static pattern stem: `' # File does not exist. # File has not been updated. # automatic # @ := all # automatic # % := # automatic # * := # automatic # + := make.txt # automatic # | := # automatic # < := all # automatic # ^ := make.txt # automatic # ? := |
When asking about target information on line 3, we now see that a
number of automatic variables have been set. We can also get
information about just these variables using the command target
all variables
or info locals
:
mdb<1> info locals @ := all % := * := + := make.txt | := < := all ^ := make.txt ? := |
The target “all” doesn't have any commands associated with it. If we
next
to a target that does, we can see a full expansion of the
command that is about to be run:
mdb<2> next /tmp/remake/src/test2:5 File `make.txt' does not exist. (/tmp/remake/src/test2:5): make.txt mdb<3> target make.txt commands make.txt: # commands to execute (from `test2', line 6): makeinfo --no-headers $< > $@ mdb<4> examine makeinfo --no-headers $< > $@ makeinfo --no-headers ../doc/mdb.texi > make.txt |
Another way to do the above target
and examine
commands
in one go is ito use the “expand” option on the target
command
rather than the “commands” option:
mdb<5> target @ expand make.txt: # commands to execute (from `test2', line 6): -makeinfo --no-headers $< > $ # commands to execute (from `test2', line 6): -makeinfo --no-headers ../doc/mdb.texi > make.txt |
Notice instead of giving the target name make.txt
, @
works as well.
Now if we want to write out those commands as a shell script which
we might want to execute, we can use the write
(Write commands of a target (‘write’))
command:
(/tmp/remake/src/test2:6): make.txt mdb<6> write File "/tmp/make.txt.sh" written. mdb<7> shell cat -n /tmp/make.txt.sh 1 #!/bin/sh 2 # cd /tmp/remake/src/ 3 #/tmp/remake/src/test2:5 4 makeinfo --no-headers ../doc/mdb.texi > make.txt 5 |
And last we see that we can even issue a shell command (cat -n
/tmp/make.txt.sh
) via the debugger command shell
. (See
Running Shell commands ( ‘shell’).)
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
the GNU Make debugger is free software, protected by the GNU General Public License (GPL). The GPL gives you the freedom to copy or adapt a licensed program—but every person getting a copy also gets with it the freedom to modify that copy (which means that they must get access to the source code), and the freedom to distribute further copies. Typical software companies use copyrights to limit your freedoms; the Free Software Foundation uses the GPL to preserve these freedoms.
Fundamentally, the General Public License is a license which says that you have these freedoms and that you cannot take these freedoms away from anyone else.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The biggest deficiency in the free software community today is not in the software—it is the lack of good free documentation that we can include with the free software. Many of our most important programs do not come with free reference manuals and free introductory texts. Documentation is an essential part of any software package; when an important free software package does not come with a free manual and a free tutorial, that is a major gap. We have many such gaps today.
Consider Perl, for instance. The tutorial manuals that people normally use are non-free. How did this come about? Because the authors of those manuals published them with restrictive terms—no copying, no modification, source files not available—which exclude them from the free software world.
That wasn't the first time this sort of thing happened, and it was far from the last. Many times we have heard a GNU user eagerly describe a manual that he is writing, his intended contribution to the community, only to learn that he had ruined everything by signing a publication contract to make it non-free.
Free documentation, like free software, is a matter of freedom, not price. The problem with the non-free manual is not that publishers charge a price for printed copies—that in itself is fine. (The Free Software Foundation sells printed copies of manuals, too.) The problem is the restrictions on the use of the manual. Free manuals are available in source code form, and give you permission to copy and modify. Non-free manuals do not allow this.
The criteria of freedom for a free manual are roughly the same as for free software. Redistribution (including the normal kinds of commercial redistribution) must be permitted, so that the manual can accompany every copy of the program, both on-line and on paper.
Permission for modification of the technical content is crucial too. When people modify the software, adding or changing features, if they are conscientious they will change the manual too—so they can provide accurate and clear documentation for the modified program. A manual that leaves you no choice but to write a new manual to document a changed version of the program is not really available to our community.
Some kinds of limits on the way modification is handled are acceptable. For example, requirements to preserve the original author's copyright notice, the distribution terms, or the list of authors, are ok. It is also no problem to require modified versions to include notice that they were modified. Even entire sections that may not be deleted or changed are acceptable, as long as they deal with nontechnical topics (like this one). These kinds of restrictions are acceptable because they don't obstruct the community's normal use of the manual.
However, it must be possible to modify all the technical content of the manual, and then distribute the result in all the usual media, through all the usual channels. Otherwise, the restrictions obstruct the use of the manual, it is not free, and we need another manual to replace it.
Please spread the word about this issue. Our community continues to lose manuals to proprietary publishing. If we spread the word that free software needs free reference manuals and free tutorials, perhaps the next person who wants to contribute by writing documentation will realize, before it is too late, that only free manuals contribute to the free software community.
If you are writing documentation, please insist on publishing it under the GNU Free Documentation License or another free documentation license. Remember that this decision requires your approval—you don't have to let the publisher decide. Some commercial publishers will use a free license if you insist, but they will not propose the option; it is up to you to raise the issue and say firmly that this is what you want. If the publisher you are dealing with refuses, please try other publishers. If you're not sure whether a proposed license is free, write to licensing@gnu.org.
You can encourage commercial publishers to sell more free, copylefted manuals and tutorials by buying them, and particularly by buying copies from the publishers that paid for their writing or for major improvements. Meanwhile, try to avoid buying non-free documentation at all. Check the distribution terms of a manual before you buy it, and insist that whoever seeks your business must respect your freedom. Check the history of the book, and try to reward the publishers that have paid or pay the authors to work on it.
The Free Software Foundation maintains a list of free documentation published by other publishers, at http://www.fsf.org/doc/other-free-books.html.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This chapter discusses how to start the GNU Make debugger, and how to get out of it. The essentials are:
You don't have to use the command-line interface. At present there is
a front-end available via GNU Emacs which can be entered
via the Emacs command M-x mdb
after loading Emacs' Grand
Unified Debugger, gud
. See Using the GNU Make debugger from GNU Emacs. In the future there may be support in a DDD
as well.
2.1 Starting the GNU Make debugger | How to enter the the GNU Make debugger | |
2.2 Quitting the GNU Make debugger | How to leave the the GNU Make debugger |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Note: it is important to use a debugger-enabled GNU Make. You will get usage help output if a patched GNU Make is not used.
As mentioned above, one can enter the GNU Make debugger via Emacs (and perhaps later DDD). However you don't have to use either of these. And these still need a way on their own to get things started.
The enter the GNU Make debugger from a command line, use the ‘--debugger’ or it's short form ‘-X’ option:
make --debugger other-make-arguments... make -X other-make-arguments... |
This runs GNU Remake as it would normally do; that is Makefiles are read and dependencies are checked. However it is in a “stepping” mode and will go into the debugger read loop when before encounter in “interesting” target. An “interesting” target is one that has commands associated with it to rebuild the target.
A suboption to the --debugger
(or -X
) option specifies
under what conditions to enter the debugger; it is specified by
putting an equals sign (`=') and then the suboption; for example:
make -X=preread other-make-arguments... |
Here is a full list of debugger options and suboptions...
--debugger [preread | preaction | full | error | fatal]
-X [preread | preaction | full | error | fatal]
The “preread” suboption enters the debugger after command-line options are parsed but before any Makefiles have been read. It also puts GNU Remake in step-tracing mode and sets the debugger to enter if it encounters an error.
The “preaction” suboption enters the debugger after command-line options are parsed and after Makefiles have been read, but before any action is performed. It also puts GNU Remake in step-tracing mode and sets the debugger to enter if it encounters an error.
The “error” suboption enters the debugger when it encounters an
error. Depending on other conditions, GNU Remake can ignore errors
and continue processing. So the overall effect could be like the
--keep-going
flag.
The “fatal” suboption enters the debugger when it encounters a fatal error. A fatal error generally cause GNU Remake to abort execution.
The “full” suboption is just a convenience for giving the “enter,” “error,” and “fatal” options described above. execution.
If no suboption is provided, “full” is assumed.
--no-extended-errors
This option causes GNU Remake to not print a target stack trace if it encounters an error.
--trace [=suboption]
-x
Causes target names which have commands associated with them to get printed before they are considered. If a target has multiple commands each one is printed before they are run whether or not the command has the GNU Remake @ specifier which would otherwise cause them not to echo.
This option also allows for suboptions, read
, normal
,
and full
. The default is normal
; read
adds
tracing as Makefiles are read.
tracing is independent of the --debugger
option and can be used
in conjunction with it. Inside the debugger one can have the same
effect by issuing the debugger set trace on
command.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
An interrupt (often C-c) does not exit from the GNU Make debugger, but
rather terminates the action of any the GNU Make debugger command that is in
progress and returns to the GNU Make debugger command level. Inside a debugger
command interpreter however C-c, C-d, and quit
will terminate the program. (See see section Quitting the Make debugger).
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
You can abbreviate the long name of the GNU Make debugger command to the first
few letters of the command name, if that abbreviation is unambiguous;
and you can repeat the next
o rstep
commands by typing
just <RET>. Some commands which require a parameter, such as
print
remember the argument that was given to them.
3.1 Command syntax | How to give commands to the the GNU Make debugger | |
3.2 Getting help (‘help’) | How to ask for help (help) | |
3.3 Quitting the GNU Make debugger (‘quit’) | Leaving the debugger (quit) | |
3.4 Stopping and Resuming Execution | Stopping and continuing (break, watch, step, cont...) | |
3.5 Status and Debugger Settings (‘info’, ‘show’, ‘set’) | Status and Debugger settings (info, show) | |
3.6 Examining the Stack (‘where’, ‘frame’, ‘up’, ‘down’) | Examining the stack (where, up, down, frame) | |
3.7 Examining Data | Examining data (print, target, examine, info variables) | |
3.8 Evaluation and Execution | Arbitrary execution (eval, shell) | |
3.9 Interfacing to the OS (‘cd’, ‘pwd’) | Interfacing to the OS (cd, pwd) | |
3.10 Controlling the GNU Make debugger (‘set’) | Controlling make (annotate, file, prompt...) |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
A GNU Remake debugger command is a single line of input. There is
no limit on how long it can be. It starts with a command name, which
is followed by arguments whose meaning depends on the command name.
For example, the command step
accepts an argument which is the
number of times to step, as in ‘step 5’. You can also use the
step
command with no arguments. Some commands do not allow any
arguments. In commands that have attributes, the attribute can be
abbreviated to the minimum string that makes it unique. For example
“commands”in target all commands
can be shortened to
“command” or “com” or just “c”.
A blank line as input to the GNU Make debugger (typing just <RET>) means to repeat the previous next or step command.
Any text from a # to the end of the line is a comment; it does nothing. This is useful mainly in command files
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Once inside the debugger, you can always ask it for information on its
commands, using the command help
.
help
h
You can use help
(abbreviated h
) with no arguments to
display a short list of named classes of commands:
mdb<0> help Command Short Name Aliases ---------------------- ---------- --------- break *target* (b) L comment *text* (#) continue [target] (c) delete breakpoint numbers.. (d) down [amount] (D) eval *string* (e) examine *string* (x) finish (F) frame *n* (f) help [command] (h) ?, ?? info [thing] (i) next [amount] (n) print {*variable* [attrs...]} (p) quit [exit-status] (q) exit, return run (R) restart set {*option*|variable} *value* (=) setq *variable* *value* (") shell *string* (!) !! show [thing] (S) skip (k) step [amount] (s) target (t) up [amount] (u) where (T) backtrace, bt write [*target* [*filename*]] (w) Readline command line editing (emacs/vi mode) is available. For more detailed help, type h <cmd> or consult online-documentation. |
help command
With a command name as help
argument, GNU Remake displays
short information on how to use that command.
mdb<3> help where where: Show target stack. |
In addition to help
, you can use the debugger command
info
to inquire about the state of your script, or the state of
the GNU Make debugger itself. The listings under info
in the Index
point to all the sub-commands. See section Command Index.
info
This command (abbreviated i
) is for describing the state of
your program. For example, you can list the arguments given to your
script with info args
. You can get a complete list of the
info
sub-commands with help info
.
mdb<0> help info info [thing]: Show the state of thing. If no 'thing' is specified, show everything there is to show. Available info subcommands are: line locals makefiles target variables warranty |
Subcommands can be abbreviated with the minimum number of letters to
make that subcommand distinct from another. For example info lo
is the same as info locals
and info li
is the same as
info line
.
info line
Shows the line number and file of for the place that you are currently stopped.
info locals
Displays a the values of the automatic variables.
info makefiles
Displays the list of Makefiles read in the order that they were read in. The last Makefile listed is the one you started with (e.g. Makefile).
info target
Displays target information.
info warranty
Displays GNU Warranty
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
quit [return-code]
q [return-code]
To exit the GNU Make debugger, use the quit
command (abbreviated
q
), or type an end-of-file character (usually C-d). If
you do not supply return-code, the GNU Make debugger will terminate
normally or with exit code 0. Otherwise it use the value of the
return-code as the exit code. Usually a 0 exit is a normal exit.
Often when running GNU Remake, a recursive call is made or made in
another directory. The quit
only terminates only the last one:
the one that the debugger is in. The GNU Remake debugger arranges for the debug
flags to get passed down in recursive calls. Consequently when you
quit one of the inner make calls, you may find yourself still in the
debugger but up a call level.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
One important use of a debugger is to stop execution before it gets into trouble, so you can investigate and find out what is going on. However should GNU Remake accidentally continue to termination, the GNU Make debugger has arranged for it not to leave the debugger without your explicit instruction. That way, you can restart the program using the same command arguments.
Inside the GNU Make debugger, your script may stop for any of several reasons,
such as a signal, a breakpoint, or reaching a new line after a
debugger command such as step
. You may then examine and
change variables, set new breakpoints or remove old ones, and then
continue execution.
3.4.1 Breakpoints | Breakpoints, watchpoints (break, clear) | |
3.4.2 Resuming Execution | Resuming execution (continue, step, next, skip) | |
3.4.3 Signals |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
A breakpoint arranges for GNU Remake to stop whenever a certain point in the Makefile is reached.
You can set breakpoints with the break
command and its variants
(see section Setting breakpoints), to specify the place where
your script should stop by target name.
3.4.1.1 Setting breakpoints (‘break’) | Setting breakpoints (break) | |
3.4.1.2 Deleting breakpoints (‘delete’) | Deleting breakpoints (delete, clear) |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Breakpoints are set with the break
command (abbreviated
b
).
break target
Set a breakpoint at target in the current Makefile.
Examples:
mdb<0> break all Breakpoint on target all set. |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
It may be desirable to eliminate a breakpoint once it has done its job and you no longer want stop there. This is called deleting the breakpoint. A breakpoint that has been deleted no longer exists; it is forgotten.
It is not necessary to delete a breakpoint to proceed past it. the GNU Make debugger automatically ignores breakpoints on the first instruction to be executed when you continue execution.
delete breakpoint-number...
Delete the breakpoints by breakpoint-number specified as arguments.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Continuing means resuming program execution until your script completes normally. In contrast, stepping means executing just one more “step” of your script, where “step” may mean either one line of source code. Either when continuing or when stepping, your script may stop even sooner, due to a breakpoint or a signal.
3.4.2.1 Next (‘next’) | running the next statement (next) | |
3.4.2.2 Step (‘step’) | running the next statement in small increments (step) | |
3.4.2.3 Skip (‘skip’) | skipping the next statement (skip) | |
3.4.2.4 Continue (‘continue’) | continuing execution (continue) |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
next
Continue processing your Makefile until control reaches a different
interesting source line, then stop it and return control to
the GNU Make debugger. This command is abbreviated n
.
next [count]
Continue running as in next
, count times. If a
breakpoint is reached, or a signal not related to stepping occurs before
count steps, stepping stops right away.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
step
Stepping is like next
but it is more fine-grained. It will stop
at every target that needs to be remade whether or not there are
commands associated with it.
If there are multiple commands associated with a target step
will stop before each one.
step [count]
Continue running as in step
, so count times. If a
breakpoint is reached, or a signal not related to stepping occurs before
count steps, stepping stops right away.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
skip [count]
Skip executing the remaining commands of the target you are stopped at. This may be useful if you have an action that “fixes” existing code in a Makefile.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
continue [target]
Resume program execution, at the address where your script last stopped. If you specify a target name, a breakpoint is set at that target before contining. If the target is invalid though, an error is given and we don't continue.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
A signal is an asynchronous event that can happen in a program. The
operating system defines the possible kinds of signals, and gives each
kind a name and a number. For example, in Unix SIGINT
is the
signal a program gets when you type an interrupt character (often
C-c); SIGALRM
occurs when the alarm clock timer goes off
(which happens only if your program has requested an alarm).
GNU Remake sets up some signal handlers of children it spawns. When we are running under the debugger when and we get a signal the debugger read loop is entered.
Some signals, including SIGALRM
, are a normal part of the
functioning of your program. Others, such as SIGSEGV
, indicate
errors; these signals are fatal (they kill your program
immediately) if the program has not specified in advance some other
way to handle the signal. SIGINT
does not indicate an error in
your program, but it is normally fatal so it can carry out the purpose
of the interrupt: to kill the program.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
In addition to help
, you can use the GNU Make debugger commands
info
and show
to inquire about the state of your
program, or the state of GNU Remake itself. Each command supports
many topics of inquiry; here we introduce each of them in the
appropriate context. The listings under info
in the Index
point to all the sub-commands. See section Command Index.
info
This command (abbreviated i
) is for describing the state of
your debugger setting. For example, you can show whether GNU Remake
has set to ignore errors or not.
set
In addition to showing GNU Remake settings you can change them or
change GNU Remake variables with set
. For example, you can
change setting GNU Remake has whether to ignore errors.
show
In contrast to info
, show
is for describing the state of
GNU Remake itself.
You can change most of the things you can show
, by using the
related command set
;
The distinction between info
and show
however is a bit
fuzzy and is kept here to try to follow the GDB interface.
To display all the settable parameters and their current
values, you can use show
with no arguments; you may also use
info set
. Both commands produce the same display.
Here are force miscellaneous show
subcommands, all of which are
exceptional in lacking corresponding set
commands:
show command
Shows the list of commands previously entered
show version
Show what version of GNU Remake is running. You should include this information in the GNU Make debugger bug-reports. If multiple versions of GNU Remake are in use at your site, you may need to determine which version you are running; as the GNU Make debugger evolves, new commands are introduced, and old ones may wither away. The version number is the same as the one announced when you start GNU Remake.
show warranty
Display the GNU “NO WARRANTY” statement, or a warranty, if your version of the GNU Make debugger comes with one.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
When you enter the debugger, one thing you'll probably want to know is where it stopped and some idea of how it got there.
Each time your Makefile performs dependency checking (sometimes as implicit rules or pattern-substitution rules), information about the target that caused the new target to be considered action is saved on a stack. This target call stack then is this a history of the dependency checks that got you to the point that you are currently stopped at.
One of the stack frames is selected by the GNU Make debugger and many the GNU Make debugger commands refer implicitly to the selected frame. In particular, whenever you ask the GNU Make debugger to list lines without giving a line number or location the value is found in the selected frame. There are special the GNU Make debugger commands to select whichever frame you are interested in. See section Selecting a frame.
When your program stops, the GNU Make debugger automatically selects the
currently executing frame and describes it briefly, similar to the
frame
command.
3.6.1 Stack frames | ||
3.6.2 Backtraces (‘where’) | Backtraces (where) | |
3.6.3 Selecting a frame (‘up’, ‘down’, ‘frame’) | Selecting a frame (up, down, frame) | |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The target stack is divided up into contiguous pieces called stack frames, or frames for short. The frame contains the line number of the target which triggered the next one to be considered, the Makefile file name that the line in that refers to a target name. When some of this information is be missing you may see a filename shown as “null” or have line number 0.
When your script is started, the stack has only one frame, that of the
function main
. This is called the initial frame or the
outermost frame. Each time a function is called, a new frame is
made. Each time a function returns, the frame for that function invocation
is eliminated. If a function is recursive, there can be many frames for
the same function. The frame for the function in which execution is
actually occurring is called the innermost frame. This is the most
recently created of all the stack frames that still exist.
the GNU Make debugger assigns numbers to all existing stack frames, starting with zero for the innermost frame, one for the frame that called it, and so on upward. These numbers do not really exist in your script; they are assigned by the GNU Make debugger to give you a way of designating stack frames in the GNU Make debugger commands.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
A backtrace is essentially the same as the call stack: a summary of how your script got where it is. It shows one line per frame, for many frames, starting with the place that you are stopped at (frame zero), followed by its caller (frame one), and on up the stack.
If GNU Remake is in the reading phase the backtrace shows the nesting of include files. If GNU Remake is in the interpretation phase the backtrace shows the nesting of targets.
where
backtrace
bt
T
If we are reading Makefiles, print a backtrace of the included Makefile stack. If we are evaluating the Makefile to bring targets up to date, print a backtrace of the target stack. In either case, we print line per frame.
where n
backtrace n
bt n
T n
Similar, but print only the innermost n frames. A negative number prints the outermost n frames.
Each line in the backtrace shows the frame number and the function name, the source file name and line number, as well as the function name.
Here is an example of a backtrace taken a program in the regression-tests ‘parm.sh’.
./make -X /tmp/remake/src/Makefile:228: Makefile.in mdb<0> step /tmp/remake/src/Makefile:263: make mdb<1> where =>#0 make at /tmp/remake/src/Makefile:263 #1 all-am at /tmp/remake/src/Makefile:386 #2 all at /tmp/remake/src/Makefile:224 |
However if we have set debugging to stop before reading makefiles are we are in the reading phase, we show included Makefiles:
$ ./make --debugger=preread Reading makefiles... Reading makefile `Makefile'... (/tmp/remake/src/Makefile:1) mdb<0> step /tmp/remake/src/Makefile:324 Reading makefile `.deps/alloca.Po' (search path) (no ~ expansion)... (/tmp/remake/src/.deps/alloca.Po:1) mdb<1> where =>#0 /tmp/remake/src/.deps/alloca.Po:1 #1 /tmp/remake/src/Makefile:324 mdb<2> next /tmp/remake/src/Makefile:327 Reading makefile `.deps/getloadavg.Po' (search path) (no ~ expansion)... /tmp/remake/src/Makefile:328 Reading makefile `.deps/ar_fns.Po' (search path) (no ~ expansion)... /tmp/remake/src/Makefile:329 ... lots of lines deleted ... Reading makefile `.deps/version.Po' (search path) (no ~ expansion)... /tmp/remake/src/Makefile:360 Reading makefile `.deps/vpath.Po' (search path) (no ~ expansion)... Updating goal targets.... /tmp/remake/src/Makefile:254 File `all' does not exist. (/tmp/remake/src/Makefile:254): all mdb<3> |
Note in the above ‘step’ goes on to the next read of a makefile while the ‘next’ command can be used to skip over all of the remaining reads.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Commands for printing targets script work on whichever stack frame is selected at the moment. Here are the commands for selecting a stack frame; all of them finish by printing a brief description of the stack frame just selected.
up n
Move n frames up the stack. For positive numbers n, this advances toward the outermost frame, to higher frame numbers, to frames that have existed longer. n defaults to one.
down n
Move n frames down the stack. For positive numbers n, this
advances toward the innermost frame, to lower frame numbers, to frames
that were created more recently. n defaults to one. You may
abbreviate down
as do
.
All of these commands end by printing two lines of output describing the frame. The first line shows the frame number, the function name, the arguments, and the source file and line number of execution in that frame. The second line shows the text of that source line.
For example:
mdb<8> up /tmp/remake/src/Makefile:386: all-am mdb<8> T #0 make at /tmp/remake/src/Makefile:263 =>#1 all-am at /tmp/remake/src/Makefile:386 #2 all at /tmp/remake/src/Makefile:224 |
frame args
The frame
command allows you to move from one stack frame to
another, and to print the stack frame you select. args is the
the stack frame number. Without an argument, frame
prints the
current stack frame.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
3.7.1 Print variable info (‘print’) | Print variable info | |
3.7.2 Print a string expanded (‘examine’) | Print a string expanded | |
3.7.3 Examining Targets (‘target’) | Print target Info | |
3.7.4 “Listing” Targets (‘list’) | List-like target Info | |
3.7.5 Write commands of a target (‘write’) | Write commands of a target | |
3.7.6 Print all variables (‘info variables’) | Print all variables |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
One way to examine variables the print
command (abbreviated p
). However a more versatile print command
is x
; it can print arbitrary string expands which of course
includes variable.
print variable-name
Use print
to display GNU Remake's variables. As such,
variable names should not be preceded with a dollar sign.
mdb<0> print SHELL Makefile:168 (origin: makefile) SHELL = /bin/sh /tmp/remake/Makefile:243: Makefile.in mdb<1> print $MAKE # don't use $ Can't find variable $MAKE /tmp/remake/Makefile:243: Makefile.in mdb<1> print shell # note case is significant Can't find variable shell |
print
p
If you omit variable, the GNU Make debugger displays the last expression again.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
x string
The x
command expands the string given using GNU Remake's
internal variables. The expansion would be the same as if the string
were given as a command inside the target.
mdb<0> examine MAKE (origin default) MAKE := /tmp/remake/src/./make /tmp/remake/src/Makefile:264: Makefile.in mdb<1> print MAKE # note the difference with the ``print'' (origin default) MAKE = $(MAKE_COMMAND) mdb<2> examine $(MAKE) # Note using $( ) doesn't matter here... /tmp/remake/src/./make # except in output format - no origin info /tmp/remake/src/Makefile:264: Makefile.in mdb<2> p COMPILE Makefile:104 (origin: makefile) COMPILE := $(CC) $(DEFS) $(DEFAULT_INCLUDES) /tmp/remake/src/Makefile:264: Makefile.in mdb<10> x compile starts: $(CC) $(DEFS) $(DEFAULT_INCLUDES) compile starts: gcc -DLOCALEDIR=\"\" -DLIBDIR=\"/usr/local/lib\" -DINCLUDEDIR=\"/usr/local/include\" -DHAVE_CONFIG_H -I. -I.. |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
the GNU Make debugger can print information about targets. When your script stops, the GNU Make debugger spontaneously prints the line and target name where it stopped. Likewise, when you select a stack frame (see section Selecting a frame), the GNU Make debugger the default target name is changed.
target
t
print information about the current target.
target target
t target
Print information about target. A list of attributes can be specified after the target name. The list of attributes names are
Show the list of “attributes” associated with the target. Attributes can be:
Show the list of commands that need to get run in order to bring the target up to date.
Show the targets that this one depends on.
Show the list of commands that need to get run in order to bring the target up to date with GNU Remake variables expanded.
Show the dependencies that are not ordered.
Show status of target:
This shows the time that the file was last modified and if the file has been brought up to date. If it is not up to date you will see the message “File is very old.” If a target is “phony”, i.e. doesn't have file associated with it, the message “File does not exist.” will appear instead of the time. In some cases you may see “Modification time never checked.”
Show single-character automatic state variables (if defined):
Note that there are other automatic variables defined based on
these. In particular those that have a `D' or `F' suffix, e.g. $(@D),
or $(*F). These however are not listed here but can shown in a
print
command or figured out from their corresponding
single-letter variable name.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This is really a short-hand for issing a target
commmand with
parameters depends
and comamnds
.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
write [target [filename|here]]
Use this to write the command portion of a target with GNU Remake's internal variables expanded. If a filename is given that is the file where the expanded commands are written. If the filename is “here” then it is not written to a file but output inside the debugger as other debugger command behaves. And if no file name is given a filename based on the target name is created.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
info variables
If you want to all list variables, use this command.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
3.8.1 Subsection Evaluating GNU MAKE commands ( ‘eval’) | Evaluate a GNU Makefile string | |
3.8.2 Running Shell commands ( ‘shell’) | Execute a Shell command |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
eval command string
e
A powerful command is the ability to enter MAKE fragments and have
them interpreted on the fly. This can be done using the eval
command. For example to “include” a makefile, you might enter
eval include ...
. Some of the other commands given
elsewhere can be performed by eval
. In particular, instead of
using the “setq” debugger command, one could issue the command as
eval VAR=value
.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
shell command string
!
If you need to execute occasional shell commands during your
debugging session, there is no need to leave or suspend the GNU Make debugger; you can
just use the shell
command or its alias !
.
Invoke a shell to execute command string.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
cd
Set working directory to directory for debugger and program being debugged. The change does not take effect for the program being debugged until the next time it is started.
pwd
!
Prints the working directory as the program sees things.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
You can alter the way GNU Remake interacts with you in various ways given below.
3.10.1 Basename (‘set basename’) | Annotation Level (set basename) | |
3.10.2 Ignoring errors (‘set ignore-errors’) | Ignoring errors | |
3.10.3 Tracing (‘set basename’) | Set tracing | |
3.10.4 Setting a variable to an expanded string (‘set variable’) | Set a variable to an expanded string | |
3.10.5 Setting a variable to an unexpanded string (‘setq’) | Set a variable to an unexpanded string |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
set basename on/off/toggle
The basename level controls how much information the GNU Make debugger prints when it has to show a file name. When this is on we just show the base filename part an not the path info. When the GNU Make debugger is run as a subprocess of GNU Emacs of DDD, it is important to show full pathnames.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
set ignore-errors on/off/toggle
Use this to change whether you ignore errors. Turning it on is
as though you started GNU Remake with the --ignore-errors
option.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
set trace on/off/toggle
Use this to change whether you want tracing or not. Turning it on is
as though you started GNU Remake with the --trace
option.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Sets variable to the value string, but string is
expanded first as it would be when you use examine
.
One nice use of set variable in debugging is to set the value of
SHELL
to include tracing in that. Here's an example:
mdb<0> set variable SHELL $(SHELL) -x Variable SHELL now has value '/bin/sh -x' mdb<1> |
Now we'll show this in a real example - stepping (or actually “next”ing though the top-level makefile in the source distribution for GNU Remake:
$ remake -X Reading makefiles... (/tmp/remake/Makefile:256) Makefile.in: Makefile.am config/readline.m4 gettext.m4 iconv.m4 lib-ld.m4 lib-link.m4 lib-prefix.m4 progtest.m4 acinclude.m4 configure.ac aclocal.m4 mdb<0> set variable SHELL $(SHELL) -x Variable SHELL now has value '/bin/sh -x' mdb<1> n Updating goal targets.... /tmp/remake/Makefile:250 File `all' does not exist. (/tmp/remake/Makefile:250) all: config.h mdb<2> p SHELL Makefile:156 (origin: debugger) SHELL = /bin/bash -x mdb<3> n Prerequisite `stamp-h1' is newer than target `config.h'. /tmp/remake/Makefile:288 Must remake target `config.h'. (/tmp/remake/Makefile:288) config.h: stamp-h1 mdb<4> n if test ! -f config.h; then \ rm -f stamp-h1; \ remake stamp-h1; \ else :; fi + test '!' -f config.h + : /tmp/remake/Makefile:288 Successfully remade target file `config.h'. |
Above we see the script source code followed by the trace information – we took the “else” branch which has the null statement “:”.
Probably in the future, we'll arrange some stepping or tracing
mode perform this SHELL reassignment trick of adding -x
.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
setq variable string
Sets variable to the value string, but string is
not expanded first as it is not you use print
.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The only front-ends that can use the GNU Make debugger as a back-end debugger is GNU Emacs. In the future an interface via DDDmay be available.
4.1 Using the GNU Make debugger from GNU Emacs | ||
4.2 Using GNU Remake from DDD | Using the GNU Make debugger from DDD |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
A special interface allows you to use GNU Emacs to view (and edit) the source files for the program you are debugging with the GNU Make debugger.
To use this interface, use the command M-x mdb in GNU Emacs. Give the executable file you want to debug as an argument. This command starts the GNU Make debugger as a subprocess of GNU Emacs, with input and output through a newly created GNU Emacs buffer.
Using the GNU Make debugger under GNU Emacs is just like using the GNU Make debugger normally except for two things:
This applies both to the GNU Make debugger commands and their output, and to the input and output done by the program you are debugging.
This is useful because it means that you can copy the text of previous commands and input them again; you can even use parts of the output in this way.
All the facilities of Emacs' Shell mode are available for interacting with your script. In particular, you can send signals the usual way—for example, C-c C-c for an interrupt, C-c C-z for a stop.
Each time the GNU Make debugger displays a stack frame, Emacs automatically finds the source file for that frame and puts an arrow (‘=>’) at the left margin of the current line. Emacs uses a separate buffer for source display, and splits the screen to show both your the GNU Make debugger session and the source.
Explicit the GNU Make debugger list
or search commands still produce output as
usual, but you probably have no reason to use them from Emacs.
Warning: If the directory where your script resides is not your current directory, it can be easy to confuse Emacs about the location of the source files, in which case the auxiliary display buffer does not appear to show your source. the GNU Make debugger can find programs by searching your environment's
PATH
variable, so the the GNU Make debugger input and output session proceeds normally; but Emacs does not get enough information back from the GNU Make debugger to locate the source files in this situation. To avoid this problem, either start the GNU Make debugger mode from the directory where your script resides, or specify an absolute file name when prompted for the M-x gdb argument.A similar confusion can result if you use the the GNU Make debugger
file
command to switch to debugging a program in some other location, from an existing the GNU Make debugger buffer in Emacs.
By default, M-x mdb calls the make --debugger
. If you
need to call the GNU Make debugger by a different name (for example, if you
keep several configurations around, with different names) you can set
the Emacs variable gud-mdb-command-name
; for example,
(setq gud-mdb-command-name "make") |
(preceded by M-: or ESC :, or typed in the *scratch*
buffer, or
in your ‘.emacs’ file) makes Emacs call the program named
“mdb
” instead.
In the the GNU Make debugger I/O buffer, you can use these special Emacs commands in addition to the standard Shell mode commands:
Describe the features of Emacs' the GNU Make debugger Mode.
Execute to another source line, like the the GNU Make debugger step
command; also
update the display window to show the current file and location.
Execute to next source line in this function, skipping all function
calls, like the the GNU Make debugger next
command. Then update the display window
to show the current file and location.
Execute until exit from the selected stack frame, like the the GNU Make debugger
finish
command.
Continue execution of your script, like the the GNU Make debugger continue
command.
Warning: In Emacs v19, this command is C-c C-p.
Go up the number of frames indicated by the numeric argument
(see (Emacs)Arguments section `Numeric Arguments' in The GNU Emacs Manual),
like the the GNU Make debugger up
command.
Warning: In Emacs v19, this command is C-c C-u.
Go down the number of frames indicated by the numeric argument, like the
the GNU Make debugger down
command.
Warning: In Emacs v19, this command is C-c C-d.
In any source file, the Emacs command C-x SPC (gud-break
)
tells the GNU Make debugger to set a breakpoint on the source line point is on.
If you accidentally delete the source-display buffer, an easy way to get
it back is to type the command frame
in the the GNU Make debugger buffer, to
request a frame display; when you run under Emacs, this recreates
the source buffer if necessary to show you the context of the current
frame.
The source files displayed in Emacs are in ordinary Emacs buffers which are visiting the source files in the usual way. You can edit the files with these buffers if you wish; but keep in mind that the GNU Make debugger communicates with Emacs in terms of line numbers. If you add or delete lines from the text, the line numbers that the GNU Make debugger knows cease to correspond properly with the code.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
GNU Remake support is rather new in DDD. As a programming language, GNU Remake is not feature rich: there are no record structures or hash tables (yet), no pointers, package variable scoping or methods. So much of the data display and visualization features of DDD are disabled.
As with any scripting or interpreted language (e.g. Perl), one can't step by a single machine-language instruction. So the ddd Stepi/Nexti commands are disabled.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Your bug reports play an essential role in making the GNU Remake reliable.
Reporting a bug may help you by bringing a solution to your problem, or it may not. But in any case the principal function of a bug report is to help the entire community by making the next version of GNU Remake work better. Bug reports are your contribution to the maintenance of GNU Remake.
In order for a bug report to serve its purpose, you must include the information that enables us to fix the bug.
5.1 Have you found a bug? | ||
5.2 How to report bugs |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
If you are not sure whether you have found a bug, here are some guidelines:
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Submit bug reports for GNU Remake. Until better mechanism is set up the preferred method is to submit them directly using rocky@panix.com. There are also a bug tracking system and, help, developer and open discussion forums which can be found via http://http://sourceforge.net/forum/?group_id=37260.
Although this code shares a lot with BASH, the debugger is of course
not yet supported by the BASH team, so if there is a debugger problem
reporting it via bashbug or to bug-bash@gnu.org or posted to
the newsgroup gnu.bash.bug
probably won't help, unless you are
sure the bug resides in the vanilla bash code and and show that.
The fundamental principle of reporting bugs usefully is this: report all the facts. If you are not sure whether to state a fact or leave it out, state it!
Often people omit facts because they think they know what causes the problem and assume that some details do not matter. Thus, you might assume that the name of the variable you use in an example does not matter. Well, probably it does not, but one cannot be sure. Perhaps the bug is a stray memory reference which happens to fetch from the location where that name is stored in memory; perhaps, if the name were different, the contents of that location would fool the debugger into doing the right thing despite the bug. Play it safe and give a specific, complete example. That is the easiest thing for you to do, and the most helpful.
Keep in mind that the purpose of a bug report is to enable us to fix the bug. It may be that the bug has been reported previously, but neither you nor we can know that unless your bug report is complete and self-contained.
Sometimes people give a few sketchy facts and ask, “Does this ring a bell?” Those bug reports are useless, and we urge everyone to refuse to respond to them except to chide the sender to report bugs properly.
To enable us to fix the bug, you should include all these things:
version
command.
Without this, we will not know whether there is any point in looking for the bug in the current version of GNU Remake.
gcc
–3.1”.
If we were to try to guess the arguments, we would probably guess wrong and then we might not encounter the bug.
Of course, if the bug is that GNU Remake gets a fatal signal, then we will certainly notice it. But if the bug is incorrect output, we might not notice unless it is glaringly wrong. You might as well not give us a chance to make a mistake.
Even if the problem you experience is a fatal signal, you should still say so explicitly. Suppose something strange is going on, such as, your copy of GNU Remake is out of synch, or you have encountered a bug in the C library on your system. (This has happened!) Your copy might crash and ours would not. If you told us to expect a crash, then when ours fails to crash, we would know that the bug was not happening for us. If you had not told us to expect a crash, then we would not be able to draw any conclusion from our observations.
The line numbers in our development sources will not match those in your sources. Your line numbers would convey no useful information to us.
Here are some things that are not necessary:
Often people who encounter a bug spend a lot of time investigating which changes to the input file will make the bug go away and which changes will not affect it.
This is often time consuming and not very useful, because the way we will find the bug is by running a single example under the debugger with breakpoints, not by pure deduction from a series of examples. We recommend that you save your time for something else.
Of course, if you can find a simpler example to report instead of the original one, that is a convenience for us. Errors in the output will be easier to spot, running under the debugger will take less time, and so on.
However, simplification is not vital; if you do not want to do this, report the bug anyway and send us the entire test case you used.
A patch for the bug does help us if it is a good one. But do not omit the necessary information, such as the test case, on the assumption that a patch is all we need. We might see problems with your patch and decide to fix the problem another way, or we might not understand it at all.
Sometimes with a program as complicated as GNU Remake it is very hard to construct an example that will make the program follow a certain path through the code. If you do not send us the example, we will not be able to construct one, so we will not be able to verify that the bug is fixed.
And if we cannot understand what bug you are trying to fix, or why your patch should be an improvement, we will not install it. A test case will help us to understand.
Such guesses are usually wrong. Even we cannot guess right about such things without first using the debugger to find the facts.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
My idea for a debugger for GNU Remake came about on working on a debugger for bash (http://bashdb.sourceforge.net). I knew the bash debugger was good enough when it was able to debug autoconf-generated script which are tens of thousands of lines long.
But almost immediately after scaling this new height, I became sunk deep in depression when I realized that to debug the configuration mess I also needed to deal with Makefiles, if not also autoconf, and automake as well.
After seeing an article on the auto-configuration mess http://freshmeat.net/articles/view/889 I posted a query to ask if anyone was interested in writing a debugger for GNU Remake.
Almost year later and no takers, I was reminded of my query by accident when I got a query from one of the GNU mailing lists that I am on about slow e-mail posting to the GNU Make mailing list.
I again suggested the idea of a debugger and was told how incredibly difficult it would be to write a debugger and how incredibly unique GNU Make is. At that point I looked into the code and to my surprise and delight I found that in contrast to BASH the code, GNU Make is much smaller and written in a more modern coding style (although certainly it could use much improvement). In fact, it had most of the information stored that would be helpful in a debugger. All I would need to do is add a GNU readline for the debug loop, extend to save a target stack and track line numbers and report line numbers better. But this last part I'd been through with the bash debugger.
All in all, I've been very pleased at how far I've been able to get with much less effort than needed for the bash debugger. That's not to say that much work isn't still needed or that the overall design couldn't be improved.
This documentation was modified from the GNU Bash Debugger (bashdb) Reference manual (which in turn was modified from GNU Bash debugger (gdb).
Additions to this section are particularly welcome. If you or your friends (or enemies, to be evenhanded) have been unfairly omitted from this list, we would like to add your names!
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Jump to: | !
#
B C D E F H I N P Q R S U W X |
---|
Jump to: | !
#
B C D E F H I N P Q R S U W X |
---|
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Jump to: | -
B C D E F G H I L O P R S T V |
---|
Jump to: | -
B C D E F G H I L O P R S T V |
---|
[Top] | [Contents] | [Index] | [ ? ] |
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.
or “jobs” in the
terminology used when we used --debug
Actually the output is a little bit different here since we give a more context about the position when a fatal error is encountered.
for a while I thought there was a bug in
remake
since I the default goal target all
is not
listed. But the above is correct. In fact, GNU Make first tries
to remake the Makefile it has read in. See “How Makefiles are
Remade” in the GNU Make manual for details.
[Top] | [Contents] | [Index] | [ ? ] |
[Top] | [Contents] | [Index] | [ ? ] |
This document was generated on March, 11 2010 using texi2html 1.78.
The buttons in the navigation panels have the following meaning:
Button | Name | Go to | From 1.2.3 go to |
---|---|---|---|
[ < ] | Back | Previous section in reading order | 1.2.2 |
[ > ] | Forward | Next section in reading order | 1.2.4 |
[ << ] | FastBack | Beginning of this chapter or previous chapter | 1 |
[ Up ] | Up | Up section | 1.2 |
[ >> ] | FastForward | Next chapter | 2 |
[Top] | Top | Cover (top) of document | |
[Contents] | Contents | Table of contents | |
[Index] | Index | Index | |
[ ? ] | About | About (help) |
where the Example assumes that the current position is at Subsubsection One-Two-Three of a document of the following structure:
This document was generated on March, 11 2010 using texi2html 1.78.