DXREADME
9.96 KB
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
264
265
266
267
268
269
270
DX DEBUG PACKAGE for IDL
MARKWARDT IDL PROGRAMS
Craig Markwardt
craigm@cow.physics.wisc.edu
17 Apr 2000
The following instructions apply to the DXDEBUG package of procedures
for command line debugging under IDL, available from the Markwardt IDL
Library.
The procedures in the package supply convenience routines for
navigating up and down the IDL call stack (DXUP and DXDOWN); for
interogating and modifying IDL variables at any levels in the call
stack (DXHELP, DXPRINT, DXGET, DXSET); and for quickly setting and
clearing breakpoints (DXBREAK, DXFINISH and DXCLEAR).
These routines are really only meant to be useful when actively
debugging a stopped program -- they are probably *not* acceptable to
be called as library routines from other procedures.
DOWNLOADING
Download new versions of from Craig Markwardt's web page:
http://cow.physics.wisc.edu/~craigm/idl/idl.html
Program modification dates appear on the web page, which you can
compare agains your own copy. You can also check the modification
history of the file itself to see how recent it is.
Please see the file INSTALL for installation instructions.
MANIFEST
DXREADME - this file - package description and instructions
INSTALL - general installation instructions
DXUP - navigate up the IDL call stack (toward outermost level)
DXDOWN - navigate down the IDL call stack (toward innermost level)
DXGET - function to retrieve variable value at any call level
DXSET - set a variable value at any call level
DXPRINT - equivalent of PRINT for any call level
DXHELP - equivalent of HELP for any call level
DXBREAK - set breakpoints more conveniently than BREAKPOINT
DXFINISH - set breakpoint at return of current procedure
DXCLEAR - clear breakpoints
DXLRESET - internal routine
DXPLEVEL - internal routine
DXPTRACE - internal reoutine
INTRODUCTION
Command line debugging with IDL has always been difficult. It does
provide excellent abilities to interactively query and set variables,
but only at one level -- the deepest level. Generally, when debugging
a larger suite of programs one can have procedures and functions that
nest several levels deep. Since one procedure can call another, or
even itself, this is a natural effect. If an error occurs in a
procedure several levels deep, knowing the values of variables at
higher levels (i.e., the calling routines) can be useful and time
saving. Unfortunately IDL has no documented provisions for doing
this.
The DXDEBUG package provides several convenience routines to do
examine variables at any call level. The package is based upon
invaluable discussions about the undocumented ROUTINE_NAMES() function
on the comp.lang.idl-pvwave Usenet newsgroup.
DXDEBUG also has convenience routines which aid in setting
breakpoints. I have always found it difficult to deal with
breakpoints for because:
* it is cumbersome to type long commands;
* it is difficult to remember or type full path to procedure name;
* there is no easy way to break when the current procedure finishes.
I have tried to remedy this with the DXBREAK and DXFINISH procedures.
THE IDL CALL STACK
When your program crashes, and you type HELP, you get a report similar
to the following:
% At XTE_OPEN 15 /home/craigm/lib/idl/xte/xte_open.pro
% XSORTINPUT 76 /home/craigm/lib/idl/idlextract/xsortinput.pro
% BINLC 299 /home/craigm/lib/idl/idlextract/binlc.pro
This output indicates that you are currently stopped in a program
which is three "levels" deep. That is, the BINLC procedure has called
XSORTINPUT, which in turn has called XTE_OPEN. In fact the stopped
program is *four* levels deep, if you consider that the $MAIN$ level
as another level (which you should).
This set of levels is the IDL *call stack*. It describes from where
each procedure has called the next. The *deepest* level is considered
to be innermost. When IDL crashes or stops, it is always at the
deepest level. The *upper- or outermost* level is the main level that
you started at. Now let's try the DXHELP command to see the call
stack again:
IDL> dxhelp
1 $MAIN$ 0
2 BINLC 299 /home/craigm/lib/idl/idlextract/binlc.pro
3 XSORTINPUT 76 /home/craigm/lib/idl/idlextract/xsortinput.pro
>> 4 XTE_OPEN 15 /home/craigm/lib/idl/xte/xte_open.pro <<
This is essentially the same information as produced by HELP, but the
one important difference is the highlighting of the deepest level with
angled brackets (>> <<). While IDL itself always stays at the deepest
level, you can use DXUP and DXDOWN to move up and down the stack and
examine variables.
MOVING UP and DOWN THE STACK
By typing DXUP, we can move one level up the call stack, like this:
IDL> dxup
>> 3 XSORTINPUT 76 /home/craigm/lib/idl/idlextract/xsortinput.pro <<
DXUP reports that we have moved up to level 3, XSORTINPUT. If we want
to see the entire call stack we can always type DXHELP again.
*What* exactly has moved up? IDL itself always stays at the lowest
level, but all of the DXDEBUG commands maintain a separate notion of
what level you are currently examining -- which can be any level in
the call stack. This level is referred to the "debugging focus"
level.
As you might suspect, DXDOWN will move us down one level. In this
case it would return us to the lowest XTE_OPEN level we started at.
Let's not do that right now. It should also be obvious that you
cannot go any deeper than the deepest level, or any higher than the
uppermost $MAIN$ level. You will be warned if you try.
EXAMINING VARIABLES
Now that we have moved the debugging focus to the level of XSORTINPUT,
we can try looking at the variables there. Periscope up!
You can use DXHELP and DXPRINT like the standard HELP and PRINT
commands.
IDL> dxhelp, sz
>> 3 XSORTINPUT 76 /home/craigm/lib/idl/idlextract/xsortinput.pro <<
SZ LONG = Array[4]
DXHELP always prints at least the current level to prevent confusion.
In this case it also shows that SZ is a 4-element long integer array.
DXPRINT actually prints the values:
IDL> dxprint, sz
>> 3 XSORTINPUT 76 /home/craigm/lib/idl/idlextract/xsortinput.pro <<
1 1 7 1
You can use the standard FORMAT keywords if you need to.
CHANGING VARIABLES
Sometimes you may need to actually change the value of a variable.
Two routines, DXGET and DXSET will help you do this. If you first
need to retrieve the value of a variable, use DXGET.
IDL> x = dxget('sz')
IDL> print, x
1 1 7 1
In this case we have retrieved the value of SZ from the current
debugging focus level (level 3, XSORTINPUT), and put the value in the
variable X. Notice that it is not required to type quotes around the
variable name, but it is good practice to do so.
After setting any new values, use DXSET to actually alter the upper
level value:
IDL> x(2) = 8
IDL> dxset, 'sz', x
Now the new value will be established.
One note: you have to DXGET an entire variable. You will not be able
to retrieve subscripted arrays or structure tags.
SETTING BREAKPOINTS
Until now, there was one thing I never did when debugging a program:
set breakpoints. The BREAKPOINT command just never seemed convenient.
Why? Well, you just couldn't avoid typing a lot of letters. The
BREAKPOINT command itself is pretty long, and then you have to type
either /SET or /CLEAR. The worst offender, however, was having to
type the complete path to the procedure being debugged. In the era of
multi-gigabyte hard drives, that path was often a pretty long one to
type. So I just never got excited about breakpoints and instead put
in manual debugging statements.
I am trying to change, and I hope you will too.
The DXBREAK command has fewer characters to type, and *most*
importantly, DXBREAK does not required to type the complete path name.
If you don't type the full path, DXBREAK will automatically scan your
IDL_PATH to find the right file. In fact, if you only enter a line
number, then DXBREAK will automatically set the breakpoint in the
current file!
Remember, breakpoints can only be set in procedures or files that are
compiled from disk. This means that RESTORE'd procedures, or
procedures compiled from the console, cannot have breakpoints.
As an example, try:
IDL> dxbreak, 'xsortinput', 70
Breakpoint set at: XSORTINPUT 70 (/home/craigm/lib/idl/idlextract/xsortinput.pro)
This sets a breakpoint at line 70 in the xsortinput.pro file. As you
can see, the full path to the file was discovered automatically. To
confirm that the breakpoint was set, we can do the standard HELP
command:
IDL> help, /break
Breakpoints:
Index Module Line File
----- ------ ---- ----
0 XSORTINPUT 70 /home/craigm/lib/idl/idlextract/xsortinput.pro
Clear breakpoints with BREAKPOINT, /CLEAR or DXCLEAR.
The other thing I found wanting in debugging was the ability to let
the current procedure finish, BUT THEN STOP. Often the true bug is in
the calling procedure, so we want to let the current deepest level
finish so we can do a more detailed analysis one level up.
DXFINISH is the answer to these desires. Just type it by itself, and
it will automatically set a breakpoint in the procedure or function
one level up, at the next line of execution. Do it like this:
IDL> dxfinish
Breakpoint set at: XSORTINPUT 77
Then we simply continue and IDL will stop when the breakpoint is hit:
IDL> .continue
% Breakpoint at: XSORTINPUT 77 /home/craigm/lib/idl/idlextract/xsortin
Note that by default DXFINISH uses the /ONCE keyword to set these
kinds of breakpoints. This means that the breakpoint will be cleared
after it has been hit once. This behavior is usually what is
intended, but it can be overridden by using the ONCE=0 keyword to
DXFINISH.
CONCLUSION
I hope that this package will help you debug smarter and faster. I've
just begun to use them myself, so there may still be some bugs.
Please let me know if you have any to report, or any other comments.
Thanks.