1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
|
_dnl__ -*- Texinfo -*-
_dnl__ Copyright (c) 1991 Free Software Foundation, Inc.
_dnl__ This file is part of the source for the GDB manual.
@c M4 FRAGMENT: $Id$
@node Sample Session, Invocation, New Features, Top
@chapter A Sample _GDBN__ Session
You can use this manual at your leisure to read all about _GDBN__.
However, a handful of commands are enough to get started using the
debugger. This chapter illustrates these commands.
@iftex
In this sample session, we emphasize user input like this: @i{input},
to make it easier to pick out from the surrounding output.
@end iftex
@c FIXME: this example may not be appropriate for some configs, where
@c FIXME...primary interest is in remote use.
_0__
One of the preliminary versions of GNU @code{m4} (a generic macro
processor) exhibits the following bug: sometimes, when we change its
quote strings from the default, the commands used to capture one macro's
definition in another stop working. In the following short @code{m4}
session, we define a macro @code{foo} which expands to @code{0000}; we
then use the @code{m4} builtin @code{defn} to define @code{bar} as the
same thing. However, when we change the open quote string to
@code{<QUOTE>} and the close quote string to @code{<UNQUOTE>}, the same
procedure fails to define a new synonym @code{baz}:
@smallexample
$ @i{cd gnu/m4}
$ @i{./m4}
@i{define(foo,0000)}
@i{foo}
0000
@i{define(bar,defn(`foo'))}
@i{bar}
0000
@i{changequote(<QUOTE>,<UNQUOTE>)}
@i{define(baz,defn(<QUOTE>foo<UNQUOTE>))}
@i{baz}
@i{C-D}
m4: End of input: 0: fatal error: EOF in string
@end smallexample
@noindent
Let's use _GDBN__ to try to see what's going on.
@smallexample
$ @i{_GDBP__ m4}
Reading symbol data from m4...done.
(_GDBP__)
@end smallexample
@noindent
_GDBN__ only reads enough symbol data to know where to find the rest
when needed; as a result, the first prompt comes up very quickly. We
then tell _GDBN__ to use a narrower display width than usual, so
that examples will fit in this manual.
@smallexample
(_GDBP__) @i{set width 70}
@end smallexample
@noindent
Let's see how the @code{m4} builtin @code{changequote} works.
Having looked at the source, we know the relevant subroutine is
@code{m4_changequote}, so we set a breakpoint there with _GDBN__'s
@code{break} command.
@smallexample
(_GDBP__) @i{break m4_changequote}
Breakpoint 1 at 0x62f4: file builtin.c, line 879.
@end smallexample
@noindent
Using the @code{run} command, we start @code{m4} running under _GDBN__
control; as long as control does not reach the @code{m4_changequote}
subroutine, the program runs as usual:
@smallexample
(_GDBP__) @i{run}
Starting program: /work/Editorial/gdb/gnu/m4/m4
@i{define(foo,0000)}
@i{foo}
0000
@end smallexample
@noindent
To trigger the breakpoint, we call @code{changequote}. _GDBN__
suspends execution of @code{m4}, displaying information about the
context where it stops.
@smallexample
@i{changequote(<QUOTE>,<UNQUOTE>)}
Breakpoint 1, m4_changequote (argc=3, argv=0x33c70) at builtin.c:879
879 if (bad_argc(TOKEN_DATA_TEXT(argv[0]), argc, 1, 3))
@end smallexample
@noindent
Now we use the command @code{n} (@code{next}) to advance execution to
the next line of the current function.
@smallexample
(_GDBP__) @i{n}
882 set_quotes((argc >= 2) ? TOKEN_DATA_TEXT(argv[1]) : nil,
@end smallexample
@noindent
@code{set_quotes} looks like a promising subroutine. We can go into it
by using the command @code{s} (@code{step}) instead of @code{next}.
@code{step} goes to the next line to be executed in @emph{any}
subroutine, so it steps into @code{set_quotes}.
@smallexample
(_GDBP__) @i{s}
set_quotes (lq=0x34c78 "<QUOTE>", rq=0x34c88 "<UNQUOTE>")
at input.c:530
530 if (lquote != def_lquote)
@end smallexample
@noindent
The summary display showing the subroutine where @code{m4} is now
suspended (and its arguments) is called a stack frame display. We can
use the @code{backtrace} command (which can also be spelled @code{bt}),
to see where we are in the stack: it displays a stack frame for each
active subroutine.
@smallexample
(_GDBP__) @i{bt}
#0 set_quotes (lq=0x34c78 "<QUOTE>", rq=0x34c88 "<UNQUOTE>")
at input.c:530
#1 0x6344 in m4_changequote (argc=3, argv=0x33c70) at builtin.c:882
#2 0x8174 in expand_macro (sym=0x33320) at macro.c:242
#3 0x7a88 in expand_token (obs=0x0, t=209696, td=0xf7fffa30)
at macro.c:71
#4 0x79dc in expand_input () at macro.c:40
#5 0x2930 in main (argc=0, argv=0xf7fffb20) at m4.c:195
@end smallexample
@noindent
Let's step through a few more lines to see what happens. The first two
times, we can use @samp{s}; the next two times we use @code{n} to avoid
falling into the @code{xstrdup} subroutine.
@smallexample
(_GDBP__) @i{s}
0x3b5c 532 if (rquote != def_rquote)
(_GDBP__) @i{s}
0x3b80 535 lquote = (lq == nil || *lq == '\0') ? def_lquote :\
xstrdup(lq);
(_GDBP__) @i{n}
536 rquote = (rq == nil || *rq == '\0') ? def_rquote : xstrdup\
(rq);
(_GDBP__) @i{n}
538 len_lquote = strlen(rquote);
@end smallexample
@noindent
The last line displayed looks a little odd; let's examine the variables
@code{lquote} and @code{rquote} to see if they are in fact the new left
and right quotes we specified. We can use the command @code{p}
(@code{print}) to see their values.
@smallexample
(_GDBP__) @i{p lquote}
$1 = 0x35d40 "<QUOTE>"
(_GDBP__) @i{p rquote}
$2 = 0x35d50 "<UNQUOTE>"
@end smallexample
@noindent
@code{lquote} and @code{rquote} are indeed the new left and right quotes.
Let's look at some context; we can display ten lines of source
surrounding the current line, with the @code{l} (@code{list}) command.
@smallexample
(_GDBP__) @i{l}
533 xfree(rquote);
534
535 lquote = (lq == nil || *lq == '\0') ? def_lquote : xstrdup\
(lq);
536 rquote = (rq == nil || *rq == '\0') ? def_rquote : xstrdup\
(rq);
537
538 len_lquote = strlen(rquote);
539 len_rquote = strlen(lquote);
540 @}
541
542 void
@end smallexample
@noindent
Let's step past the two lines that set @code{len_lquote} and
@code{len_rquote}, and then examine the values of those variables.
@smallexample
(_GDBP__) @i{n}
539 len_rquote = strlen(lquote);
(_GDBP__) @i{n}
540 @}
(_GDBP__) @i{p len_lquote}
$3 = 9
(_GDBP__) @i{p len_rquote}
$4 = 7
@end smallexample
@noindent
That certainly looks wrong, assuming @code{len_lquote} and
@code{len_rquote} are meant to be the lengths of @code{lquote} and
@code{rquote} respectively. Let's try setting them to better values.
We can use the @code{p} command for this, since it'll print the value of
any expression---and that expression can include subroutine calls and
assignments.
@smallexample
(_GDBP__) p len_lquote=strlen(lquote)
$5 = 7
(_GDBP__) p len_rquote=strlen(rquote)
$6 = 9
@end smallexample
@noindent
Let's see if that fixes the problem of using the new quotes with the
@code{m4} built-in @code{defn}. We can allow @code{m4} to continue
executing with the @code{c} (@code{continue}) command, and then try the
example that caused trouble initially:
@smallexample
(_GDBP__) @i{c}
Continuing.
@i{define(baz,defn(<QUOTE>foo<UNQUOTE>))}
baz
0000
@end smallexample
@noindent
Success! The new quotes now work just as well as the default ones. The
problem seems to have been just the two typos defining the wrong
lengths. We'll let @code{m4} exit by giving it an EOF as input.
@smallexample
@i{C-D}
Program exited normally.
@end smallexample
@noindent
The message @samp{Program exited normally.} is from _GDBN__; it
indicates @code{m4} has finished executing. We can end our _GDBN__
session with the _GDBN__ @code{quit} command.
@smallexample
(_GDBP__) @i{quit}
$
_1__@end smallexample
|