]>
Commit | Line | Data |
---|---|---|
b3fda246 PJ |
1 | # GDB macros for use with Quagga. |
2 | # | |
3 | # Macros in this file are not daemon specific. E.g., OS or Quagga library | |
4 | # APIs. | |
5 | # | |
6 | # The macro file can be loaded with 'source <filename>'. They can then be | |
7 | # called by the user. Macros that explore more complicated structs generally | |
8 | # take pointer arguments. | |
9 | # | |
10 | # E.g.: | |
11 | # | |
12 | # (gdb) source ~paul/code/quagga/gdb/lib.txt | |
13 | # (gdb) break bgp_packet.c:613 | |
14 | # Breakpoint 3 at 0x7fa883033a32: file bgp_packet.c, line 613. | |
15 | # (gdb) cont | |
16 | # ... | |
17 | # (gdb) cont | |
18 | # Breakpoint 3, bgp_write_packet (peer=0x7fa885199080) at bgp_packet.c:614 | |
9b6d8fcf | 19 | # 614 if (CHECK_FLAG (adv->path->peer->cap,PEER_CAP_RESTART_RCV) |
b3fda246 PJ |
20 | # (gdb) dump_prefix4 &adv->rn->p |
21 | # IPv4:10.1.1.0/24 | |
22 | # (gdb) dump_prefix &adv->rn->p | |
23 | # IPv4:10.1.1.0/24 | |
24 | # | |
25 | ||
26 | ||
27 | define def_ntohs | |
28 | set $data = (char *)$arg0 | |
29 | set $i = 0 | |
30 | ||
31 | set $_ = $data[$i++] << 8 | |
32 | set $_ += $data[$i++] | |
33 | end | |
34 | document def_ntohs | |
35 | Read a 2-byte short at the given pointed to area as big-endian and | |
36 | return it in $_ | |
37 | ||
38 | Argument: Pointer to a 2-byte, big-endian short word. | |
39 | Returns: Integer value of that word in $_ | |
40 | end | |
41 | ||
42 | define def_ntohl | |
43 | set $data = (char *)$arg0 | |
44 | set $i = 0 | |
45 | ||
46 | set $_ = $data[$i++] << 24 | |
47 | set $_ += $data[$i++] << 16 | |
48 | set $_ += $data[$i++] << 8 | |
49 | set $_ += $data[$i++] | |
50 | end | |
51 | document def_ntohl | |
52 | Read a 4-byte integer at the given pointed to area as big-endian and | |
53 | return it in $_ | |
54 | ||
55 | Argument: Pointer to a big-endian 4-byte word. | |
56 | Returns: Integer value of that word in $_ | |
57 | end | |
58 | ||
59 | # NB: This is in more complicated iterative form, rather than more | |
60 | # conventional and simpler recursive form, because GDB has a recursion limit | |
61 | # on macro calls (I think). | |
62 | define walk_route_table_next | |
63 | # callee saves | |
64 | set $_top = $top | |
65 | set $_node = $node | |
66 | set $_prevl = $prevl | |
67 | ||
68 | set $top = (struct route_node *)$arg0 | |
69 | set $node = (struct route_node *)$arg1 | |
70 | set $prevl = $node | |
71 | ||
72 | # first try left | |
73 | #echo try left\n | |
74 | set $node = $prevl->link[0] | |
75 | ||
76 | # otherwise try right | |
77 | if ($node == 0) | |
78 | #echo left null, try right\n | |
79 | set $node = $prevl->link[1] | |
80 | end | |
81 | ||
82 | # otherwise go up, till we find the first right that | |
83 | # we havn't been to yet | |
84 | if ($node == 0) | |
85 | set $node = $prevl | |
86 | while ($node != $top) | |
87 | #echo right null, try up and right\n | |
88 | ||
89 | set $prevl = $node | |
90 | set $parent = $node->parent | |
91 | set $node = $parent->link[1] | |
92 | ||
93 | if ($node != 0 && $node != $prevl) | |
94 | #echo found node \n | |
95 | loop_break | |
96 | end | |
97 | ||
98 | #echo go up\n | |
99 | set $node = $parent | |
100 | end | |
101 | end | |
102 | ||
103 | #printf "next node: 0x%x\n", $node | |
104 | ||
105 | set $_ = $node | |
106 | ||
107 | set $top = $_top | |
108 | set $node = $_node | |
109 | set $prevl = $_prevl | |
110 | end | |
111 | document walk_route_table_next | |
112 | Return the next node to visit in the given route_table (or subset of) and | |
113 | the given current node. | |
114 | ||
115 | Arguments: | |
116 | 1st: (struct route_node *) to the top of the route_table to walk | |
117 | 2nd: (struct route_node *) to the current node | |
118 | ||
119 | Returns: The (struct route_node *) for the next to visit in $_ | |
120 | end | |
121 | ||
122 | define walk_route_table | |
123 | set $_visited = $visited | |
124 | set $_node = $node | |
125 | set $top = $_top | |
126 | ||
127 | set $node = (struct route_node *)$arg0 | |
128 | set $top = (struct route_node *)$arg0 | |
129 | set $visited = 0 | |
130 | ||
131 | while ($node != 0) | |
132 | printf "Node: 0x%x", $node | |
133 | ||
134 | if ($node->info != 0) | |
135 | printf "\tinfo: 0x%x", $node->info | |
136 | set $visited = $visited + 1 | |
137 | end | |
138 | ||
139 | printf "\n" | |
140 | ||
141 | walk_route_table_next $top $node | |
142 | set $node = $_ | |
143 | ||
144 | # we've gotten back to the top, finish | |
145 | if ($node == $top) | |
146 | set $node = 0 | |
147 | end | |
148 | end | |
149 | printf "Visited: %u\n", $visited | |
150 | ||
151 | set $top = $_top | |
152 | set $visited = $_visited | |
153 | set $node = $_node | |
154 | end | |
155 | ||
156 | document walk_route_table | |
157 | Walk through a routing table (or subset thereof) and dump all the non-null | |
158 | (struct route_node *)->info pointers. | |
159 | ||
160 | Argument: A lib/thread.h::(struct route_node *) pointing to the route_node | |
161 | under which all data should be dumped | |
162 | end | |
163 | ||
164 | define dump_timeval | |
165 | set $tv = (struct timeval *)$arg0 | |
166 | set $day = 3600*24 | |
167 | ||
168 | if $tv->tv_sec > $day | |
169 | printf "%d days, ", $tv->tv_sec / $day | |
170 | end | |
171 | if $tv->tv_sec > 3600 | |
172 | printf "%dh", $tv->tv_sec / 3600 | |
173 | end | |
174 | if ($tv->tv_sec % 3600) > 60 | |
175 | printf "%dm", ($tv->tv_sec % 3600) / 60 | |
176 | end | |
177 | printf "%d", $tv->tv_sec % 3600 % 60 | |
178 | if $tv->tv_usec != 0 | |
179 | printf ".%06d", $tv->tv_usec | |
180 | end | |
181 | printf "s" | |
182 | end | |
183 | document dump_timeval | |
184 | Human readable dump of a (struct timeval *) argument | |
185 | end | |
186 | ||
187 | define dump_s_addr | |
188 | set $addr = (char *)$arg0 | |
189 | ||
190 | printf "%d.%d.%d.%d", $addr[0], $addr[1], $addr[2], $addr[3] | |
191 | end | |
192 | ||
193 | define dump_s6_addr | |
194 | set $a6 = (char *)$arg0 | |
195 | set $field = 0 | |
196 | ||
197 | while ($field < 16) | |
198 | set $i1 = $field++ | |
199 | set $i2 = $field++ | |
200 | ||
201 | printf "%x%x", $a6[$i1], $a6[$i2] | |
202 | ||
203 | if ($field > 2 && ($field % 4 == 0)) | |
204 | printf ":" | |
205 | end | |
206 | end | |
207 | end | |
208 | document dump_s6_addr | |
209 | Interpret the memory starting at given address as an IPv6 s6_addr and | |
210 | print in human readable form. | |
211 | end | |
212 | ||
213 | define dump_prefix4 | |
214 | set $p = (struct prefix *) $arg0 | |
215 | echo IPv4: | |
216 | dump_s_addr &($p->u.prefix4) | |
217 | printf "/%d\n", $p->prefixlen | |
218 | end | |
219 | document dump_prefix4 | |
220 | Textual dump of a (struct prefix4 *) argument. | |
221 | end | |
222 | ||
223 | define dump_prefix6 | |
224 | set $p = (struct prefix *) $arg0 | |
225 | echo IPv6: | |
226 | dump_s6_addr &($p->u.prefix6) | |
227 | printf "/%d\n", $p->prefixlen | |
228 | end | |
229 | document dump_prefix6 | |
230 | Textual dump of a (struct prefix6 *) argument. | |
231 | end | |
232 | ||
233 | define dump_prefix | |
234 | set $p = $arg0 | |
235 | ||
236 | if ($p->family == 2) | |
237 | dump_prefix4 $p | |
238 | end | |
239 | if ($p->family == 10) | |
240 | dump_prefix6 $p | |
241 | end | |
242 | end | |
243 | document dump_prefix | |
244 | Human readable dump of a (struct prefix *) argument. | |
245 | end | |
246 | ||
247 | define rn_next_down | |
248 | set $node = $arg0 | |
249 | while ($node != 0) | |
250 | print/x $node | |
251 | if ($node->link[0] != 0) | |
252 | set $node = $node->link[0] | |
253 | else | |
254 | set $node = $node->link[1] | |
255 | end | |
256 | end | |
257 | end | |
258 | ||
259 | document rn_next_down | |
260 | Walk left-down a given route table, dumping locations of route_nodes | |
261 | ||
262 | Argument: A single (struct route_node *). | |
263 | end | |
264 | ||
265 | define rn_next_up | |
266 | set $top = (struct route_node *)$arg0 | |
267 | set $node = (struct route_node *)$arg1 | |
268 | ||
269 | while ($node != $top) | |
270 | echo walk up\n | |
271 | ||
272 | set $prevl = $node | |
273 | set $parent = $node->parent | |
274 | set $node = $parent->link[1] | |
275 | ||
276 | if ($node != 0 && $node != $prevl) | |
277 | echo found a node\n | |
278 | loop_break | |
279 | end | |
280 | ||
281 | echo going up\n | |
282 | set $node = $parent | |
283 | end | |
284 | output/x $node | |
285 | echo \n | |
286 | end | |
287 | ||
288 | document rn_next_up | |
289 | Walk up-and-right from the given route_node to the next valid route_node | |
290 | which is not the given "top" route_node | |
291 | ||
292 | Arguments: | |
293 | 1st: A (struct route_node *) to the top of the route table. | |
294 | 2nd: The (struct route_node *) to walk up from | |
295 | end |