/usr/share/doc/nescc/nesc-debugging.html is in nescc 1.3.5-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
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 271 | <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type"
content="text/html; charset=ISO-8859-1">
<title>Debugging nesC code with gdb</title>
<meta name="author" content="David Gay">
</head>
<body>
<h1>Debugging nesC code in GDB</h1>
gdb does not (yet!) have a nesC-specific mode. Instead, in gdb you are
effectively debugging the C code generated by the nesC compiler.
However, the nesC compiler includes #line directives in the code it
generates, so single-stepping through nesC code will display the correct
nesC source code, and breakpoints can be set based on the line numbers
and file names of nesC components. The situation for variable,
function, command and event names is however not as straightforward. If
you wish to refer to one of these, you must use its name in the
generated C code, as explained below.<br>
<br>
When debugging tossim code, life is further complicated by the fact
that the generated C code emulates multiple motes. Thus all module
variables (but not global variables in C files) become arrays, indexed
by mote id (if the variable was itself an array, the mote id is the
first dimension). At any point in time, the "current" mote is found in <span
style="font-family: monospace;">tos_state.current_node</span>.<br>
<br>
By default, nesC does a lot of inlining, which makes debugging tricky.
In most cases, pass the -<span style="font-family: monospace;">g -O1
-fnesc-no-inline</span> options to nesC to produce code that is easier
to debug (the <span style="font-family: monospace;">debug</span> option
to the standard TinyOS Makefile does this). If you have a problem which
requires debugging fully optimised code, just include <span
style="font-family: monospace;">-g</span> and prepare for a slightly
painful experience... (the <span style="font-family: monospace;">debugopt</span>
to the standard TinyOS Makefile does this).<br>
<h2>Mapping from nesC names to C names</h2>
Types, variables and functions in C files (included via the <span
style="font-family: monospace;">includes</span> statement) are left
unchanged in the generated C code, except if they correspond to a nesC
keyword. In this last case, the name is prefixed with <span
style="font-family: monospace;">__nesc_keyword_</span>, so components
becomes <span style="font-family: monospace;">__nesc_keyword_components</span>.<br>
<br>
A module variable (top-level data declarations in modules) <span
style="font-style: italic;">X </span>in module <span
style="font-style: italic;">M</span> is called <span
style="font-style: italic;">M</span>$<span style="font-style: italic;">X</span>
in the generated C code.<br>
<br>
A function <span style="font-style: italic;">F</span> in module <span
style="font-style: italic;">M</span> is called <span
style="font-style: italic;">M</span>$<span style="font-style: italic;">F</span>
in the generated C code.<br>
<br>
Local variable names in modules are left unchanged in the generated C
code.<br>
<br>
A command or event <span style="font-style: italic;">C</span> in module <span
style="font-style: italic;">M</span> is called <span
style="font-style: italic;">M</span>$<span style="font-style: italic;">C</span>
in the generated C code.<br>
<br>
A command or event <span style="font-style: italic;">C</span> of
interface instance <span style="font-style: italic;">I</span> in module <span
style="font-style: italic;">M</span> is called <span
style="font-style: italic;">M</span>$<span style="font-style: italic;">I</span>$<span
style="font-style: italic;">C</span> in the generated C code.<br>
<br>
To complicate matters a little, gdb does not directly accept $ in
function names in <span style="font-family: monospace;">break</span>
(set a breakpoint) statements. Instead, you must precede the function
name with a *, e.g, <span style="font-family: monospace;">b
*BlinkM$StdControl$init</span>. Note that this sets a breakpoint on the
first instruction of the function (normally part of the function
preamble setting up the function's stack frame) rather than on the first
executable statement of the function. As a result, gdb may not
correctly display argument values, etc, until you single-step into the
function body.<br>
<h2>Example</h2>
This example debugs the CntToLeds application from TinyOS on a mica
mote, using on-chip debugging with a JTAG ICE pod (see <a
href="debugging.html">this document</a> for instructions on setting the
JTAG ICE up):<br>
<br>
We compile the application with debugging and no inlining by passing
the TinyOS-specific <span style="font-family: monospace;">debug</span>
option to make:<br>
<div style="margin-left: 40px;"><span style="font-family: monospace;">[dgay@barnowl
CntToLeds]$ make mica debug</span><br style="font-family: monospace;">
<span style="font-family: monospace;"> compiling
CntToLeds to a mica binary</span><br style="font-family: monospace;">
<span style="font-family: monospace;">ncc -o build/mica/main.exe -O1 -g
-fnesc-no-inline -board=micasb -target=mica -I%T/lib/Counters -Wall
-Wshadow -DDEF_TOS_AM_GROUP=0x42 -Wnesc-all -finline-limit=100000
-fnesc-cfile=build/mica/app.c CntToLeds.nc -lm</span><br
style="font-family: monospace;">
<span style="font-family: monospace;"> compiled
CntToLeds to build/mica/main.exe</span><br
style="font-family: monospace;">
<span style="font-family: monospace;">
2588 bytes in ROM</span><br style="font-family: monospace;">
<span style="font-family: monospace;">
46 bytes in RAM</span><br style="font-family: monospace;">
<span style="font-family: monospace;">avr-objcopy --output-target=srec
build/mica/main.exe build/mica/main.srec</span><br>
<span style="font-family: monospace;"></span></div>
<br>
We start ice-gdb to download and debug CntToLeds:<br>
<div style="margin-left: 40px;"><span style="font-family: monospace;">[dgay@barnowl
CntToLeds]$ ice-gdb build/mica/main.exe</span><br
style="font-family: monospace;">
<span style="font-family: monospace;">AVaRICE version 2.0.20030821cvs,
Aug 21 2003 15:36:04</span><br style="font-family: monospace;">
<span style="font-family: monospace;"> </span><br
style="font-family: monospace;">
<span style="font-family: monospace;">JTAG config starting.</span><br
style="font-family: monospace;">
<span style="font-family: monospace;">Hardware Version: 0xc0</span><br
style="font-family: monospace;">
<span style="font-family: monospace;">Software Version: 0x69</span><br
style="font-family: monospace;">
<span style="font-family: monospace;">Reported JTAG device ID: 0x9702</span><br
style="font-family: monospace;">
<span style="font-family: monospace;">Configured for device ID: 0x9702
atmega128</span><br style="font-family: monospace;">
<span style="font-family: monospace;">LockBits -> 0xff</span><br
style="font-family: monospace;">
<span style="font-family: monospace;"> </span><br
style="font-family: monospace;">
<span style="font-family: monospace;">Reading Fuse Bytes:</span><br
style="font-family: monospace;">
<span style="font-family: monospace;"> Extended Fuse byte ->
0xfd</span><br style="font-family: monospace;">
<span style="font-family: monospace;">
High Fuse byte -> 0x19</span><br style="font-family: monospace;">
<span style="font-family: monospace;">
Low Fuse byte -> 0xfe</span><br style="font-family: monospace;">
<span style="font-family: monospace;">JTAG config complete.</span><br
style="font-family: monospace;">
<span style="font-family: monospace;">Downloading FLASH image to
target......................</span><br style="font-family: monospace;">
<span style="font-family: monospace;"> </span><br
style="font-family: monospace;">
<span style="font-family: monospace;">Download complete.</span><br
style="font-family: monospace;">
<span style="font-family: monospace;">Waiting for connection on port
6423.</span><br style="font-family: monospace;">
<span style="font-family: monospace;">GNU gdb cvs-pre6.0-tinyos</span><br
style="font-family: monospace;">
<span style="font-family: monospace;">Copyright 2003 Free Software
Foundation, Inc.</span><br style="font-family: monospace;">
<span style="font-family: monospace;">GDB is free software, covered by
the GNU General Public License, and you are</span><br
style="font-family: monospace;">
<span style="font-family: monospace;">welcome to change it and/or
distribute copies of it under certain conditions.</span><br
style="font-family: monospace;">
<span style="font-family: monospace;">Type "show copying" to see the
conditions.</span><br style="font-family: monospace;">
<span style="font-family: monospace;">There is absolutely no warranty
for GDB. Type "show warranty" for details.</span><br
style="font-family: monospace;">
<span style="font-family: monospace;">This GDB was configured as
"--host=i686-pc-linux-gnu --target=avr"...</span><br
style="font-family: monospace;">
<span style="font-family: monospace;">Connection opened by host
127.0.0.1, port 33805.</span><br style="font-family: monospace;">
<span style="font-family: monospace;">0x00000000 in __vectors ()</span><br>
<span style="font-family: monospace;"></span></div>
<span style="font-family: monospace;"><br>
</span>The program is stopped. We set a breakpoint at the Timer.fired
event in the Counter module. Note the *:<span
style="font-family: monospace;"><br style="font-family: monospace;">
</span>
<div style="margin-left: 40px;"><span style="font-family: monospace;">(gdb)
b *Counter$Timer$fired</span><br style="font-family: monospace;">
<span style="font-family: monospace;">Hardware assisted breakpoint 1 at
0x826: file /home/dgay/motes/tinyos-1.x/tos/lib/Counters/Counter.nc,
line 67.</span><br>
<span style="font-family: monospace;"></span></div>
<span style="font-family: monospace;"><br>
</span>And let the program continue:<br>
<div style="margin-left: 40px;"><span style="font-family: monospace;"></span><span
style="font-family: monospace;">(gdb) c</span><br
style="font-family: monospace;">
<span style="font-family: monospace;">Continuing.</span><br
style="font-family: monospace;">
<span style="font-family: monospace;"> </span><br
style="font-family: monospace;">
<span style="font-family: monospace;">Breakpoint 1, Counter$Timer$fired
() at /home/dgay/motes/tinyos-1.x/tos/lib/Counters/Counter.nc:67</span><br
style="font-family: monospace;">
<span style="font-family: monospace;">67
state++;</span><br>
<span style="font-family: monospace;"></span></div>
<span style="font-family: monospace;"><br>
</span>The breakpont was reached. We continue again...<span
style="font-family: monospace;"><br style="font-family: monospace;">
</span>
<div style="margin-left: 40px;"><span style="font-family: monospace;">(gdb)
c</span><br style="font-family: monospace;">
<span style="font-family: monospace;">Continuing.</span><br
style="font-family: monospace;">
<span style="font-family: monospace;"> </span><br
style="font-family: monospace;">
<span style="font-family: monospace;">Breakpoint 1, Counter$Timer$fired
() at /home/dgay/motes/tinyos-1.x/tos/lib/Counters/Counter.nc:67</span><br
style="font-family: monospace;">
<span style="font-family: monospace;">67
state++;</span><br>
<span style="font-family: monospace;"></span></div>
<span style="font-family: monospace;"><br>
</span>Let's examine the state variable of the Counter module:<span
style="font-family: monospace;"><br style="font-family: monospace;">
</span>
<div style="margin-left: 40px;"><span style="font-family: monospace;">(gdb)
p Counter$state</span><br style="font-family: monospace;">
<span style="font-family: monospace;">$1 = 1</span><br>
<span style="font-family: monospace;"></span></div>
<span style="font-family: monospace;"><br>
</span>And then follow where the IntOutput.output command takes us.<span
style="font-family: monospace;"><br style="font-family: monospace;">
</span>
<div style="margin-left: 40px;"><span style="font-family: monospace;">(gdb)
n</span><br style="font-family: monospace;">
<span style="font-family: monospace;">68
return call IntOutput.output(state);</span><br
style="font-family: monospace;">
<span style="font-family: monospace;">(gdb) s</span><br
style="font-family: monospace;">
<span style="font-family: monospace;">Counter$IntOutput$output
(arg_0x84fde28=2) at
/home/dgay/motes/tinyos-1.x/tos/interfaces/IntOutput.nc:52</span><br
style="font-family: monospace;">
<span style="font-family: monospace;">52
command result_t output(uint16_t value);</span><br>
<span style="font-family: monospace;"></span></div>
<span style="font-family: monospace;"><br>
</span>The debugger shows us the command in the interface, we must step
again to reach our destination:<span style="font-family: monospace;"><br
style="font-family: monospace;">
</span>
<div style="margin-left: 40px;"><span style="font-family: monospace;">(gdb)
s</span><br style="font-family: monospace;">
<span style="font-family: monospace;">IntToLedsM$IntOutput$output
(value=2) at
/home/dgay/motes/tinyos-1.x/tos/lib/Counters/IntToLedsM.nc:70</span><br
style="font-family: monospace;">
<span style="font-family: monospace;">70
if (value & 1) call Leds.redOn();</span><br>
<span style="font-family: monospace;"></span></div>
<span style="font-family: monospace;"><br>
</span>The names of local variables (and function parameters) are
unchanged:<span style="font-family: monospace;"><br
style="font-family: monospace;">
</span>
<div style="margin-left: 40px;"><span style="font-family: monospace;">(gdb)
p value</span><br style="font-family: monospace;">
<span style="font-family: monospace;">$2 = 2</span><br>
<span style="font-family: monospace;"></span></div>
<span style="font-family: monospace;"><br>
</span>That's all folks!<span style="font-family: monospace;"><br
style="font-family: monospace;">
</span>
<div style="margin-left: 40px;"><span style="font-family: monospace;">(gdb)
quit</span><br style="font-family: monospace;">
</div>
<br>
</body>
</html>
|