1 /* BLURB lgpl
2
3 Coda File System
4 Release 5
5
6 Copyright (c) 1987-2016 Carnegie Mellon University
7 Additional copyrights listed below
8
9 This code is distributed "AS IS" without warranty of any kind under
10 the terms of the GNU Library General Public Licence Version 2, as
11 shown in the file LICENSE. The technical and financial contributors to
12 Coda are listed in the file CREDITS.
13
14 Additional copyrights
15 none currently
16
17 #*/
18
19 /*
20 *
21 * RVM internal structure debugging functions
22 *
23 */
24
25 #include <sys/types.h>
26 #include <sys/uio.h>
27 #include <stdio.h>
28 #include "rvm_private.h"
29
30 /* globals */
31
32 extern rvm_length_t page_size;
33 extern rvm_length_t page_mask;
34 extern rvm_bool_t rvm_no_log;
35 extern char *rvm_errmsg; /* internal error message buffer */
36
37 /* roots of memory structures */
38
39 /* structure cache */
40 extern long type_counts[NUM_CACHE_TYPES];
41 extern list_entry_t free_lists[NUM_CACHE_TYPES];
42 extern long pre_alloc[NUM_CACHE_TYPES];
43 extern long max_alloc[NUM_CACHE_TYPES];
44 extern long cache_type_sizes[NUM_CACHE_TYPES];
45
46 /* main structures roots */
47 extern list_entry_t seg_root; /* segment list */
48 extern tree_node_t *region_tree; /* mapped regions tree */
49 extern list_entry_t page_list; /* free page list */
50 extern list_entry_t log_root; /* log list */
51
52 /* locals */
53
54 /* structure names & sizes for debug support */
55 #ifdef DEBUG_GDB
56 static char *type_names[NUM_TYPES]
57 = {TYPE_NAMES};
58 static rvm_length_t type_sizes[NUM_TYPES]
59 = {CACHE_TYPE_SIZES,OTHER_TYPE_SIZES};
60 #define SIZE(id) (type_sizes[ID_INDEX(id)])
61 #define NAME(id) (type_names[ID_INDEX(id)])
62
63 /* address is in a structure */
64 #define IN_STRUCT(x,s,id) \
65 (((x) >= (rvm_length_t)(s)) && \
66 ((x) < (((rvm_length_t)(s))+SIZE(id))))
67
68 /* address validation: must be on rvm_length_t size boundary */
69 #define ADDR_INVALID(x) ((rvm_length_t)(x) != CHOP_TO_LENGTH((x)))
70
71 #define ADDR_INVALID_OR_NULL(x) \
72 (ADDR_INVALID(x) || ((x) == NULL))
73 #endif /* DEBUG_GDB */
74
75 /* empty routine to force loading of this module when referenced by a program
76 can also be used as a break point when a condition must be calculated */
rvm_debug(val)77 void rvm_debug(val)
78 rvm_length_t val;
79 {
80 if (val != 0)
81 printf("\nAt rvm_debug: %ld (%lx)\n",val,val);
82 }
83
84 #ifdef DEBUG_GDB
85 /* power of 2 table -- must be extended for machines with address
86 spaces greater than 32 bits */
87 #define NUM_TWOS 30
88 static rvm_length_t twos[NUM_TWOS] =
89 {
90 1<<3,1<<4,1<<5,1<<6,1<<7,1<<8,1<<9,1<<10,
91 1<<11,1<<12,1<<13,1<<14,1<<15,1<<16,1<<17,
92 1<<18,1<<19,1<<20,1<<21,1<<22,1<<23,1<<24,
93 1<<25,1<<26,1<<27,1<<28,1<<29,1<<30,1<<31,
94 -1
95 };
96 /* test ifaddress is in heap-allocated space */
in_heap(addr,buf,len)97 rvm_bool_t in_heap(addr,buf,len)
98 rvm_length_t addr; /* address to search for */
99 rvm_length_t buf; /* buffer to search */
100 rvm_length_t len; /* requested length of buffer */
101 {
102 long i;
103
104 if (buf == 0) return rvm_false; /* skip null buffers */
105
106 len += sizeof(rvm_length_t); /* compensate for malloc back ptr */
107 buf -= sizeof(rvm_length_t);
108 for (i=0; i<NUM_TWOS; i++)
109 if ((len >= twos[i]) && (len < twos[i+1]))
110 break;
111 assert(i != NUM_TWOS);
112
113 if ((addr >= buf) && (addr < (buf+twos[i])))
114 return rvm_true;
115
116 return rvm_false;
117 }
118 /* list checker -- makes sure elements of list are valid */
chk_list(hdr,silent)119 rvm_bool_t chk_list(hdr,silent)
120 list_entry_t *hdr; /* header of list to check */
121 rvm_bool_t silent; /* print only errors if true */
122 {
123 list_entry_t *entry; /* current list entry */
124 list_entry_t *prev; /* previous list entry */
125 long i = 0;
126 rvm_bool_t retval = rvm_true;
127
128 if (hdr == NULL)
129 {
130 printf(" List header is null\n");
131 return rvm_false;
132 }
133 if (ADDR_INVALID(hdr))
134 {
135 printf(" List header address invalid, hdr = %lx\n",(long)hdr);
136 return rvm_false;
137 }
138 if (hdr->is_hdr != rvm_true)
139 {
140 printf(" List header is not valid, is_hdr = %ld\n",
141 (long)hdr->is_hdr);
142 return rvm_false;
143 }
144 if (!(((long)hdr->struct_id > (long)struct_first_id) &&
145 ((long)hdr->struct_id < (long)struct_last_id)))
146 {
147 printf(" List header type is not valid, struct_id = %ld\n",
148 (long)hdr->struct_id);
149 return rvm_false;
150 }
151 if (hdr->list.length < 0)
152 printf(" List length invalid, length = %ld\n",hdr->list.length);
153 if (ADDR_INVALID_OR_NULL(hdr->nextentry))
154 {
155 printf(" List header at %lx has invalid nextentry field, ",(long)hdr);
156 printf("hdr->nextentry = %lx\n",(long)hdr->nextentry);
157 return rvm_false;
158 }
159 if (ADDR_INVALID_OR_NULL(hdr->preventry))
160 {
161 printf(" List header at %lx has invalid preventry field, ",(long)hdr);
162 printf("hdr->preventry = %lx\n",(long)hdr->nextentry);
163 return rvm_false;
164 }
165 if ((hdr->nextentry == hdr->preventry) && (hdr->nextentry == hdr))
166 {
167 if (!silent)
168 printf(" List empty\n");
169 if (hdr->list.length != 0)
170 {
171 printf(" List length invalid, length = %ld\n",
172 hdr->list.length);
173 return rvm_false;
174 }
175 return rvm_true;
176 }
177 if (!silent)
178 printf(" List length = %ld\n",hdr->list.length);
179 /* check ptrs */
180 if (ADDR_INVALID_OR_NULL(hdr->nextentry))
181 {
182 printf(" List header at %lx has invalid nextentry field, ",(long)hdr);
183 printf("hdr->nextentry = %lx\n",(long)hdr->nextentry);
184 return rvm_false;
185 }
186
187 /* check all elements of list */
188 prev = hdr;
189 entry = hdr->nextentry;
190 while (entry->is_hdr != rvm_true)
191 {
192 i++;
193 if (hdr->struct_id != entry->struct_id)
194 {
195 printf(" List entry %ld (%lx) has wrong type, struct_id = %ld, ",
196 i, (long)entry, (long)entry->struct_id);
197 printf("hdr->struct_iud = %ld\n",(long)hdr->struct_id);
198 retval = rvm_false;
199 }
200 if (entry->list.name != hdr)
201 {
202 printf(" List entry %ld (%lx) does not point to header, name = %lx\n",
203 i,(long)entry,(long)entry->list.name);
204 retval = rvm_false;
205 }
206 if (entry->preventry != prev)
207 {
208 printf(" List entry %ld (%lx)does not have correct preventry,",
209 i, (long)entry);
210 printf(" preventry = %lx\n",(long)entry->preventry);
211 retval = rvm_false;
212 }
213 if (ADDR_INVALID_OR_NULL(entry->nextentry))
214 {
215 printf(" List entry %ld (%lx) has invalid nextentry field, ",
216 i,(long)entry);
217 printf("nextentry = %lx\n",(long)entry->nextentry);
218 return rvm_false;
219 }
220 prev = entry;
221 entry = entry->nextentry;
222 }
223 /* check results */
224 if (i != hdr->list.length)
225 {
226 printf(" List length wrong, length = %ld, actual length = %ld\n",
227 hdr->list.length,i);
228 retval = rvm_false;
229 }
230 if (ADDR_INVALID_OR_NULL(hdr->preventry))
231 {
232 printf(" List header at %lx has invalid preventry field, ",(long)hdr);
233 printf("hdr->preventry = %lx\n",(long)hdr->nextentry);
234 retval = rvm_false;
235 }
236
237 if ((retval) && (!silent))
238 printf(" List is OK\n");
239
240 return retval;
241 }
242 /* structure cache free list checker */
chk_free_list(struct_id)243 rvm_bool_t chk_free_list(struct_id)
244 struct_id_t struct_id; /* type of free list to check */
245 {
246 if (!(((long)struct_id > (long)struct_first_id) &&
247 ((long)struct_id < (long)struct_last_cache_id)))
248 {
249 printf("This structure is not cached\n");
250 return rvm_false;
251 }
252
253 return chk_list(&free_lists[ID_INDEX(struct_id)],rvm_true);
254 }
255
256 /* check all free lists */
chk_all_free_lists()257 void chk_all_free_lists()
258 {
259 long i;
260
261 for (i=ID_INDEX(log_id);i < ID_INDEX(struct_last_cache_id); i++)
262 {
263 printf("Checking free list for %s\n",type_names[i]);
264 chk_free_list(INDEX_ID(i));
265 }
266 }
267 /* locate an address in simple list */
search_list(hdr,struct_id,addr)268 rvm_bool_t search_list(hdr,struct_id,addr)
269 list_entry_t *hdr; /* header of list to search */
270 struct_id_t struct_id; /* type of list to search */
271 rvm_length_t addr; /* address to search for */
272 {
273 list_entry_t *entry; /* current list entry */
274 long i = 0;
275 rvm_bool_t pr_hdr = rvm_true;
276 rvm_bool_t retval = rvm_false;
277
278 /* see if in header */
279 if (hdr == NULL)
280 return rvm_false;
281 if ((addr >= (rvm_length_t)hdr)
282 && (addr < ((rvm_length_t)hdr+addr)))
283 {
284 printf(" Address contained in %s list header at %lx\n",
285 NAME(struct_id),(long)hdr);
286 retval = rvm_true;
287 }
288
289 /* search the list */
290 entry = hdr->nextentry;
291 while (!entry->is_hdr)
292 {
293 i++;
294 if ((addr >= (rvm_length_t)entry)
295 && (addr < ((rvm_length_t)entry+SIZE(struct_id))))
296 {
297 if (pr_hdr)
298 {
299 printf(" Address contained in %s list at %lx\n",
300 NAME(struct_id),(long)hdr);
301 pr_hdr = rvm_false;
302 }
303 printf(" in entry %ld at %lx\n",i,(long)entry);
304 retval = rvm_true;
305 }
306 entry = entry->nextentry;
307 }
308 return retval;
309 }
310 /* locate an address in free page list */
in_free_page_list(addr)311 rvm_bool_t in_free_page_list(addr)
312 rvm_length_t addr; /* address to search for */
313 {
314 free_page_t *pg;
315 rvm_bool_t retval = rvm_false;
316
317 /* sanity check the list structure */
318 printf("Searching free page list\n");
319 if (!chk_list(&page_list,rvm_true))
320 return rvm_false;
321
322 /* search the pages */
323 FOR_ENTRIES_OF(page_list,free_page_t,pg)
324 {
325 if ((addr >= (rvm_length_t)pg)
326 && (addr < ((rvm_length_t)pg+pg->len)))
327 {
328 printf(" Address contained in free page entry at %lx\n",
329 (long)pg);
330 retval = rvm_true;
331 }
332 }
333
334 return retval;
335 }
336 /* locate an address in free list */
in_free_list(struct_id,addr)337 rvm_bool_t in_free_list(struct_id,addr)
338 struct_id_t struct_id; /* type of free list to search */
339 rvm_length_t addr; /* address to search for */
340 {
341
342 /* check basic list structure */
343 if (!chk_list(&free_lists[ID_INDEX(struct_id)],rvm_true))
344 return rvm_false;
345
346 /* see if addr is in any element of list */
347 return search_list(&free_lists[ID_INDEX(struct_id)],struct_id,addr);
348 }
349
350 /* locate an address in free lists (searches all) */
in_free_lists(addr)351 rvm_bool_t in_free_lists(addr)
352 rvm_length_t addr; /* address to search for */
353 {
354 rvm_bool_t retval = rvm_false;
355 long i;
356
357 for (i=ID_INDEX(log_id);i < ID_INDEX(struct_last_cache_id); i++)
358 {
359 printf("Searching free list %s\n",type_names[i]);
360 if (in_free_list(INDEX_ID(i),addr))
361 retval = rvm_true;
362 }
363
364 return retval;
365 }
366 /* mem_region_t tree node checks */
chk_mem_node(node)367 rvm_bool_t chk_mem_node(node)
368 mem_region_t *node;
369 {
370 region_t *region;
371 seg_t *seg;
372 rvm_bool_t retval = rvm_true;
373
374 /* basic memory region node checks */
375 if (ADDR_INVALID_OR_NULL(node->region))
376 {
377 printf(" Region ptr is invalid, node->object = %lx\n",
378 (long)node->region);
379 return rvm_false;
380 }
381 region = node->region;
382 if (region->links.struct_id != region_id)
383 {
384 printf(" Mem_region node at %lx does not point to",(long)node);
385 printf(" region descriptor\n");
386 return rvm_false;
387 }
388 if (ADDR_INVALID_OR_NULL(region->mem_region)
389 || ((mem_region_t *)region->mem_region != node))
390 {
391 printf(" Region descriptor at %lx does not point back to",
392 (long)region);
393 printf(" mem_region node at %lx\n",(long)node);
394 return rvm_false;
395 }
396 if (ADDR_INVALID_OR_NULL(region->seg))
397 {
398 printf(" Mem_region node at %lx region descriptor has invalid",
399 (long)node);
400 printf(" segment ptr, ptr = %lx\n",(long)region->seg);
401 return rvm_false;
402 }
403 if (region->seg->links.struct_id != seg_id)
404 {
405 printf(" Mem_region node at %lx region descriptor has invalid",
406 (long)node);
407 printf(" segment descriptor, seg = %lx\n",(long)region->seg);
408 return rvm_false;
409 }
410 /* related structure and list checks */
411 if (!chk_list(&seg_root,rvm_true))
412 return rvm_false;
413 FOR_ENTRIES_OF(seg_root,seg_t,seg)
414 if (seg == region->seg) break;
415 if ((list_entry_t *)seg == &seg_root)
416 {
417 printf(" Mem_region node at %lx region descriptor's segment",
418 (long)region);
419 printf(" descriptor is not on seg_root list, seg = %lx\n",
420 (long)region->seg);
421 retval = rvm_false;
422 }
423
424 seg = region->seg;
425 if (!chk_list(&seg->map_list,rvm_true))
426 {
427 printf(" Mem_region's region's segment's map_list is damaged,");
428 printf(" seg = %lx\n",(long)seg);
429 return rvm_false;
430 }
431 FOR_ENTRIES_OF(seg->map_list,region_t,region)
432 if (region == node->region) break;
433 if (region != node->region)
434 {
435 printf(" Mem_region node at %lx region descriptor is",(long)node);
436 printf(" not on its segment's map_list, region = %lx\n",
437 (long)node->region);
438 return rvm_false;
439 }
440 region = node->region;
441 if (region->links.struct_id != region_id)
442 {
443 printf(" Mem_region node at %lx does not point to",(long)node);
444 printf(" region descriptor\n");
445 return rvm_false;
446 }
447 if (ADDR_INVALID_OR_NULL(region->mem_region)
448 || ((mem_region_t *)region->mem_region != node))
449 {
450 printf(" Region descriptor at %lx does not point back to",
451 (long)region);
452 printf(" mem_region node at %lx\n",(long)node);
453 return rvm_false;
454 }
455 if (ADDR_INVALID_OR_NULL(region->seg))
456 {
457 printf(" Mem_region node at %lx region descriptor has invalid",
458 (long)node);
459 printf(" segment ptr, ptr = %lx\n",(long)region->seg);
460 return rvm_false;
461 }
462 if (region->seg->links.struct_id != seg_id)
463 {
464 printf(" Mem_region node at %lx region descriptor has invalid",
465 (long)node);
466 printf(" segment descriptor, seg = %lx\n",(long)region->seg);
467 return rvm_false;
468 }
469 /* related structure and list checks */
470 if (!chk_list(&seg_root,rvm_true))
471 return rvm_false;
472 FOR_ENTRIES_OF(seg_root,seg_t,seg)
473 if (seg == region->seg) break;
474 if ((list_entry_t *)seg == &seg_root)
475 {
476 printf(" Mem_region node at %lx region descriptor's segment",
477 (long)region);
478 printf(" descriptor is not on seg_root list, seg = %lx\n",
479 (long)region->seg);
480 retval = rvm_false;
481 }
482
483 seg = region->seg;
484 if (!chk_list(&seg->map_list,rvm_true))
485 {
486 printf(" Mem_region's region's segment's map_list is damaged,");
487 printf(" seg = %lx\n",(long)seg);
488 return rvm_false;
489 }
490 FOR_ENTRIES_OF(seg->map_list,region_t,region)
491 if (region == node->region) break;
492 if (region != node->region)
493 {
494 printf(" Mem_region node at %lx region descriptor is",(long)node);
495 printf(" not on its segment's map_list, region = %lx\n",
496 (long)node->region);
497 retval = rvm_false;
498 }
499
500 if (!chk_list(&seg->unmap_list,rvm_true))
501 {
502 printf(" Mem_region's region's segment's unmap_list is damaged,");
503 printf(" seg = %lx\n",(long)seg);
504 return rvm_false;
505 }
506 FOR_ENTRIES_OF(seg->unmap_list,region_t,region)
507 if (region == node->region)
508 {
509 printf(" Mem_region node at %lx region descriptor is",
510 (long)node);
511 printf(" on its segment's unmap_list, region = %lx\n",
512 (long)region);
513 retval = rvm_false; break;
514 }
515
516 return retval;
517 }
518 /* validate dev_region node */
chk_dev_node(dev_region_t * node)519 rvm_bool_t chk_dev_node(dev_region_t *node)
520 {
521 rvm_bool_t retval = rvm_true;
522 /* check validity of nv buffer ptrs */
523 if (!((node->nv_ptr == NULL) && (node->nv_buf == NULL)))
524 {
525 if (ADDR_INVALID_OR_NULL(node->nv_ptr))
526 {
527 printf(" Dev_region node at %lx has bad nv_ptr\n",(long)node);
528 retval = rvm_false;
529 }
530 if (ADDR_INVALID(node->nv_buf))
531 {
532 printf(" Dev_region node at %lx has bad nv_buf\n",(long)node);
533 retval = rvm_false;
534 }
535 }
536
537 /* check consistency of nv buffer vs. log offset */
538 if (!((node->nv_ptr != NULL)
539 && RVM_OFFSET_EQL_ZERO(node->log_offset))
540 || ((!RVM_OFFSET_EQL_ZERO(node->log_offset))
541 && (node->nv_ptr == NULL)))
542 {
543 printf(" Dev_region node at %lx has inconsistent nv_ptr",(long)node);
544 printf(" & log_offset\n");
545 retval = rvm_false;
546 }
547
548 return retval;
549 }
550 /* check validity of tree node */
chk_node(tree_node_t * node,struct_id_t struct_id)551 rvm_bool_t chk_node(tree_node_t *node, struct_id_t struct_id)
552 {
553 rvm_bool_t retval = rvm_true;
554
555 /* basic structure checks */
556 if (node->struct_id != struct_id)
557 {
558 printf(" Node at %lx has wrong struct_id, id = %d, should be %ld\'n",
559 (long)node,node->struct_id,(long)struct_id);
560 retval = rvm_false;
561 }
562 if (node->gtr != NULL)
563 if (ADDR_INVALID(node->gtr) || (node->gtr->struct_id != struct_id))
564 {
565 printf(" Node at %lx gtr ptr invalid\n",(long)node);
566 retval = rvm_false;
567 }
568 if (node->lss != NULL)
569 if (ADDR_INVALID(node->lss) || (node->lss->struct_id != struct_id))
570 {
571 printf(" Node at %lx lss ptr invalid\n",(long)node);
572 retval = rvm_false;
573 }
574
575 /* type-specific checks */
576 switch (struct_id)
577 {
578 case mem_region_id:
579 retval = chk_mem_node((mem_region_t *)node) && retval;
580 break;
581 case dev_region_id:
582 retval = chk_dev_node((dev_region_t *)node) && retval;
583 break;
584 default: assert(rvm_false);
585 }
586
587 return retval;
588 }
589 /* search mem_region tree node */
search_mem_region(addr,node)590 rvm_bool_t search_mem_region(addr,node)
591 rvm_length_t addr; /* address to search for */
592 mem_region_t *node; /* mem_region node to search */
593 {
594 rvm_bool_t retval = rvm_false;
595
596 /* check tree node */
597 if (!chk_node((tree_node_t *)node,mem_region_id))
598 return rvm_false;
599
600 /* see if address is in node */
601 if ((addr >= (rvm_length_t)node) &&
602 (addr < ((rvm_length_t)node+SIZE(mem_region_id))))
603 {
604 printf(" *** Address is in mem_region node at %lx\n",(long)node);
605 retval = rvm_true;
606 }
607
608 /* see if address is in node's vm */
609 if ((addr >= (rvm_length_t)node->vmaddr) &&
610 (addr < ((rvm_length_t)node->vmaddr+node->length)))
611 {
612 printf(" *** Address is in vm represented by mem_region node at %lx\n"
613 ,(long)node);
614 retval = rvm_true;
615 }
616
617 /* check lower branches */
618 if (node->links.node.lss != NULL)
619 if (search_mem_region(addr,(mem_region_t *)node->links.node.lss))
620 retval = rvm_true;
621 if (node->links.node.gtr != NULL)
622 if (search_mem_region(addr,(mem_region_t *)node->links.node.gtr))
623 retval = rvm_true;
624
625 return retval;
626 }
627
628 /* locate an address in region_tree */
in_region_tree(addr)629 rvm_bool_t in_region_tree(addr)
630 rvm_length_t addr; /* address to search for */
631 {
632
633 printf("Searching mapped region tree\n");
634
635 return search_mem_region(addr,(mem_region_t *)region_tree);
636 }
637 /* */
search_dev_region(addr,node)638 rvm_bool_t search_dev_region(addr,node)
639 rvm_length_t addr; /* address to search for */
640 dev_region_t *node; /* segment region node to search */
641 {
642 rvm_bool_t retval = rvm_false;
643
644 /* basic node checks */
645 if (!chk_node((tree_node_t *)node,dev_region_id))
646 return rvm_false;
647
648 /* see if addr is in node */
649 if (IN_STRUCT(addr,node,dev_region_id))
650 {
651 printf(" *** Address is in dev_region node at %lx\n",
652 (long)node);
653 retval = rvm_true;
654 }
655
656 /* see if address is in node's nv buffer */
657 if (node->nv_ptr != NULL)
658 if (in_heap(addr,(rvm_length_t)node->nv_buf,
659 node->nv_buf->alloc_len))
660 {
661 printf(" *** Address is in dev_region at %lx nv buffer\n",
662 (long)node);
663 retval = rvm_true;
664 }
665
666 /* check lower nodes */
667 if (node->links.node.lss != NULL)
668 if (search_dev_region(addr,(dev_region_t *)node->links.node.lss))
669 retval = rvm_true;
670 if (node->links.node.gtr != NULL)
671 if (search_dev_region(addr,(dev_region_t *)node->links.node.gtr))
672 retval = rvm_true;
673
674 return retval;
675 }
676 /* search region descriptor */
in_region(addr,region,n)677 rvm_bool_t in_region(addr,region,n)
678 rvm_length_t addr; /* address to search for */
679 region_t *region; /* region descriptor to search */
680 long n;
681 {
682 rvm_bool_t retval = rvm_false;
683
684 /* see if in region descriptor */
685 printf(" Searching region %ld\n",n);
686 if (IN_STRUCT(addr,region,region_id))
687 {
688 printf(" *** Address is in region descriptor at %lx\n",
689 (long)region);
690 retval = rvm_true;
691 }
692
693 return retval;
694 }
695 /* search segment descriptor */
in_seg(addr,seg,n)696 rvm_bool_t in_seg(addr,seg,n)
697 rvm_length_t addr; /* address to search for */
698 seg_t *seg; /* segment descriptor to search */
699 long n;
700 {
701 region_t *region,*region2;
702 long i = 0;
703 rvm_bool_t retval = rvm_false;
704
705 /* see if address is in descriptor */
706 printf(" Searching segment %ld\n",n);
707 if (IN_STRUCT(addr,seg,seg_id))
708 {
709 printf(" *** Address is in segment descriptor at %lx\n",
710 (long)seg);
711 retval = rvm_true;
712 }
713
714 /* see if in device name */
715 if (ADDR_INVALID_OR_NULL(seg->dev.name))
716 printf(" Segment descriptor at %lx has bad dev.name\n",
717 (long)seg);
718 else
719 if (in_heap(addr,(rvm_length_t)seg->dev.name,seg->dev.name_len))
720 {
721 printf(" *** Address is in segment at %lx device name\n",
722 (long)seg);
723 retval = rvm_true;
724 }
725
726 /* validate and scan mapping lists */
727 if (!chk_list(&seg->map_list,rvm_true))
728 {
729 printf(" Segment descriptor at %lx has bad map list\n",
730 (long)seg);
731 return retval;
732 }
733 if (!chk_list(&seg->unmap_list,rvm_true))
734 {
735 printf(" Segment descriptor at %lx has bad unmap list\n",
736 (long)seg);
737 return retval;
738 }
739 FOR_ENTRIES_OF(seg->map_list,region_t,region)
740 {
741 i++;
742 if (in_region(addr,region,i))
743 {
744 printf(" *** Address is in region descriptor at %lx\n",
745 (long)region);
746 retval = rvm_true;
747 }
748 FOR_ENTRIES_OF(seg->unmap_list,region_t,region2)
749 if (region == region2)
750 {
751 printf(" Region descriptor at %lx is on both map and unmap",
752 (long)region);
753 printf(" lists of segment descriptor at %lx\n",
754 (long)seg);
755 break;
756 }
757 }
758 i = 0;
759 FOR_ENTRIES_OF(seg->unmap_list,region_t,region)
760 {
761 i++;
762 if (in_region(addr,region,i))
763 {
764 printf(" *** Address is in region descriptor at %lx\n",
765 (long)region);
766 retval = rvm_true;
767 }
768 }
769
770 return retval;
771 }
772 /* search segment list */
in_seg_list(addr)773 rvm_bool_t in_seg_list(addr)
774 rvm_length_t addr; /* address to search for */
775 {
776 seg_t *seg;
777 long i = 0;
778 rvm_bool_t retval = rvm_false;
779
780 /* basic list checks */
781 printf("Searching segment list\n");
782 if (!chk_list(&seg_root,rvm_true))
783 return retval;
784
785 /* check each segment descriptor */
786 FOR_ENTRIES_OF(seg_root,seg_t,seg)
787 {
788 i++;
789 if (in_seg(addr,seg,i))
790 retval = rvm_true;
791 }
792
793 return retval;
794 }
795 /* locate an address in change tree */
in_seg_dict(addr,seg_dict,n)796 rvm_bool_t in_seg_dict(addr,seg_dict,n)
797 rvm_length_t addr; /* address to search for */
798 seg_dict_t *seg_dict; /* segment dictionary entry */
799 long n;
800 {
801 char *seg_name;
802 rvm_bool_t retval = rvm_false;
803
804 printf(" Searching segment dictionary entry %ld\n",n);
805 if (seg_dict->seg != NULL)
806 seg_name = seg_dict->seg->dev.name;
807 else
808 seg_name = seg_dict->dev.name;
809 if (seg_name == NULL)
810 printf("Searching change tree for UNKNOWN segment at %lx\n",
811 (long)seg_dict);
812 else
813 printf("Searching change tree for %s\n",seg_name);
814
815 if (seg_dict->seg != NULL)
816 retval = in_seg(addr,seg_dict->seg,0);
817 if (IN_STRUCT(addr,seg_dict,seg_dict_id))
818 {
819 printf(" *** Address is in seg_dict at %lx\n",(long)seg_dict);
820 retval = rvm_true;
821 }
822 if (seg_dict->dev.name != NULL)
823 if (in_heap(addr,(rvm_length_t)seg_dict->dev.name,seg_dict->dev.name_len))
824 {
825 printf(" *** Address is in device name of seg_dict at %lx\n",
826 (long)seg_dict);
827 retval = rvm_true;
828 }
829
830 if (search_dev_region(addr,(dev_region_t *)seg_dict->mod_tree.root))
831 retval = rvm_true;
832
833 return retval;
834 }
835 /* search log special function descriptor */
in_log_special(addr,special,n)836 rvm_bool_t in_log_special(addr,special,n)
837 rvm_length_t addr; /* address to search for */
838 log_special_t *special; /* log special descriptor to search */
839 long n;
840 {
841 rvm_bool_t retval = rvm_false;
842
843 /* see if in descriptor */
844 printf(" Searching special function descriptor %ld\n",n);
845 if (IN_STRUCT(addr,special,log_special_id))
846 {
847 printf(" *** Address is in log special function decriptor at %lx\n",
848 (long)special);
849 retval = rvm_true;
850 }
851
852 /* structure specific tests */
853 switch (special->rec_hdr.struct_id)
854 {
855 case log_seg_id:
856 if (in_heap(addr,(rvm_length_t)special->special.log_seg.name,
857 special->special.log_seg.name_len+1))
858 {
859 printf(" *** Address is in segment name buffer\n");
860 retval = rvm_true;
861 }
862 break;
863 default:
864 printf(" Record has unknown struct_id\n");
865 }
866
867 return retval;
868 }
869 /* search modification range descriptor */
in_range(addr,range,n)870 rvm_bool_t in_range(addr,range,n)
871 rvm_length_t addr; /* address to search for */
872 range_t *range;
873 long n;
874 {
875 rvm_bool_t retval = rvm_false;
876
877 /* see if in descriptor */
878 printf(" Searching range %ld\n",n);
879 if (IN_STRUCT(addr,range,range_id))
880 {
881 printf(" *** Address is in modification range decriptor at %lx\n",
882 (long)range);
883 retval = rvm_true;
884 }
885
886 /* see if in old value save buffer */
887 if (in_heap(addr,(rvm_length_t)range->data,range->data_len))
888 {
889 printf(" *** Address is in data buffer of range descriptor");
890 printf(" at %lx\n",(long)range);
891 retval = rvm_true;
892 }
893 if (range->nvaddr != NULL)
894 if ((addr >= (rvm_length_t)range->nvaddr) &&
895 (addr < ((rvm_length_t)range->nvaddr + range->nv.length)))
896 {
897 printf(" *** Address is in data buffer of range descriptor");
898 printf(" at %lx\n",(long)range);
899 retval = rvm_true;
900 }
901
902 /* check the region ptr */
903 if (ADDR_INVALID_OR_NULL(range->region))
904 printf(" Range at %lx has bad region ptr\n",(long)range);
905 else
906 if (range->region->links.struct_id != region_id) {
907 printf(" Region at %lx has invalid struct_id,",
908 (long)range->region);
909 printf(" struct_id = %d\n",range->region->links.struct_id);
910 }
911
912 return retval;
913 }
914 /* search transaction descriptor */
in_tid(addr,tid,n)915 rvm_bool_t in_tid(addr,tid,n)
916 rvm_length_t addr; /* address to search for */
917 int_tid_t *tid; /* transaction descriptor to search */
918 long n;
919 {
920 range_t *range;
921 long i = 0;
922 rvm_bool_t retval = rvm_false;
923
924 /* see if in descriptor */
925 printf(" Searching tid %ld\n",n);
926 if (IN_STRUCT(addr,tid,int_tid_id))
927 {
928 printf(" *** Address is in transaction decriptor at %lx\n",
929 (long)tid);
930 retval = rvm_true;
931 }
932
933 /* see if in search vector */
934 if (in_heap(addr,(rvm_length_t)tid->x_ranges,
935 tid->x_ranges_alloc*sizeof(range_t *)))
936 {
937 printf(" *** Address is in tid.x_ranges at %lx\n",(long)tid);
938 retval = rvm_true;
939 }
940
941 /* check range list and range descriptors */
942 printf(" Checking modification ranges\n");
943
944 /* need chk_tree function
945 if (!chk_tree(&tid->range_tree,rvm_true))
946 printf(" Tid at %x has damaged range tree\n",tid);
947 else
948 */
949 FOR_NODES_OF(tid->range_tree,range_t,range)
950 {
951 i++;
952 if (in_range(addr,range,i))
953 retval = rvm_true;
954 }
955
956 return retval;
957 }
958 /* search a log descriptor */
in_log(addr,log,n)959 rvm_bool_t in_log(addr,log,n)
960 rvm_length_t addr; /* address to search for */
961 log_t *log; /* log descriptor to search */
962 long n; /* position in list */
963 {
964 long i;
965 int_tid_t *tid;
966 log_special_t *special;
967 rvm_bool_t retval = rvm_false;
968
969 /* see if in descriptor */
970 printf(" Searching log %ld\n",n);
971 if (IN_STRUCT(addr,log,log_id))
972 {
973 printf(" *** Address is in log descriptor at %lx\n",(long)log);
974 retval = rvm_true;
975 }
976
977 /* check device name and raw i/o buffer */
978 if (ADDR_INVALID_OR_NULL(log->dev.name))
979 printf(" Log descriptor at %lx has bad dev.name\n",(long)log);
980 else
981 if (in_heap(addr,(rvm_length_t)log->dev.name,log->dev.name_len))
982 {
983 printf(" *** Address is in log at %lx device name\n",(long)log);
984 retval = rvm_true;
985 }
986 if (log->dev.raw_io)
987 {
988 if (in_heap(addr,(rvm_length_t)log->dev.wrt_buf,log->dev.wrt_buf_len))
989 {
990 printf(" *** Address is in log at %lx wrt_buf\n",(long)log);
991 retval = rvm_true;
992 }
993 }
994 /* check i/o vector and pad buffer */
995 if (log->dev.iov_length != 0)
996 {
997 if (ADDR_INVALID_OR_NULL(log->dev.iov))
998 printf(" Log descriptor at %lx has bad dev.iov ptr\n",(long)log);
999 else
1000 {
1001 if (in_heap(addr,(rvm_length_t)log->dev.iov,
1002 log->dev.iov_length * sizeof(struct iovec)))
1003 {
1004 printf(" *** Address is in log at %lx i/o vector\n",
1005 (long)log);
1006 retval = rvm_true;
1007 }
1008 }
1009 }
1010 if (log->dev.pad_buf_len != 0)
1011 {
1012 if (ADDR_INVALID_OR_NULL(log->dev.pad_buf))
1013 printf(" Log descriptor at %lx has bad dev.pad_buf ptr\n",
1014 (long)log);
1015 else
1016 {
1017 if (in_heap(addr,(rvm_length_t)log->dev.pad_buf,
1018 log->dev.pad_buf_len))
1019 {
1020 printf(" *** Address is in log pad buffer at %lx\n",
1021 (long)log);
1022 retval = rvm_true;
1023 }
1024 }
1025 }
1026 /* check recovery buffers */
1027 if (ADDR_INVALID_OR_NULL(log->log_buf.buf))
1028 printf(" Log descriptor at %lx has bad log_buf.malloc_buf ptr",
1029 (long)log);
1030 else
1031 {
1032 if (in_heap(addr,(rvm_length_t)log->log_buf.buf,
1033 log->log_buf.length))
1034 {
1035 printf(" *** Address is in log recovery buffer at %lx\n",
1036 (long)log);
1037 retval = rvm_true;
1038 }
1039 }
1040 if (ADDR_INVALID_OR_NULL(log->log_buf.aux_buf))
1041 printf(" Log descriptor at %lx has bad log_buf.aux_buf ptr",
1042 (long)log);
1043 else
1044 {
1045 if (in_heap(addr,(rvm_length_t)log->log_buf.aux_buf,
1046 log->log_buf.aux_length))
1047 {
1048 printf(" *** Address is in auxillary buffer log at %lx",
1049 (long)log);
1050 printf(" recovery buffer\n");
1051 retval = rvm_true;
1052 }
1053 }
1054 /* check tid and flush lists */
1055 printf(" Checking uncommitted tids\n");
1056 if (!chk_list(&log->tid_list,rvm_true))
1057 printf(" Log at %lx has damaged uncommited tid list\n",(long)log);
1058 else
1059 {
1060 i = 0;
1061 FOR_ENTRIES_OF(log->tid_list,int_tid_t,tid)
1062 {
1063 i++;
1064 if (in_tid(addr,tid,i))
1065 retval = rvm_true;
1066 }
1067 }
1068 printf(" Checking flush list\n");
1069 if (!chk_list(&log->flush_list,rvm_true))
1070 printf(" Log at %lx has damaged flush list\n",(long)log);
1071 else
1072 {
1073 i = 0;
1074 FOR_ENTRIES_OF(log->flush_list,int_tid_t,tid)
1075 {
1076 i++;
1077 if (in_tid(addr,tid,i))
1078 retval = rvm_true;
1079 }
1080 }
1081
1082 /* check immediate stream list */
1083 printf(" Checking special list\n");
1084 if (!chk_list(&log->special_list,rvm_true))
1085 printf(" Log at %lx has damaged special list\n",(long)log);
1086 else
1087 {
1088 i = 0;
1089 FOR_ENTRIES_OF(log->special_list,log_special_t,special)
1090 {
1091 i++;
1092 if (in_log_special(addr,special,i))
1093 retval = rvm_true;
1094 }
1095 }
1096
1097 /* check segment dictionary */
1098 if (log->seg_dict_vec != NULL)
1099 {
1100 if (ADDR_INVALID(log->seg_dict_vec))
1101 printf(" Log descriptor at %lx has bad seg_dict_vec ptr\n",
1102 (long)log);
1103 else
1104 {
1105 printf(" Searching segment dictionary\n");
1106 if (in_heap(addr,(rvm_length_t)log->seg_dict_vec,
1107 log->seg_dict_len*sizeof(seg_dict_t)))
1108 {
1109 printf(" *** Address is in log at %lx seg_dict_vec\n",
1110 (long)log);
1111 retval = rvm_true;
1112 }
1113 for (i = 0; i < log->seg_dict_len; i++)
1114 if (in_seg_dict(addr,&log->seg_dict_vec[i],i+1))
1115 retval = rvm_true;
1116 }
1117 }
1118
1119 return retval;
1120 }
1121 /* search log list */
in_log_list(addr)1122 rvm_bool_t in_log_list(addr)
1123 rvm_length_t addr; /* address to search for */
1124 {
1125 log_t *log;
1126 long i = 0;
1127 rvm_bool_t retval = rvm_false;
1128
1129 /* basic list checks */
1130 printf("Searching log list\n");
1131 if (!chk_list(&log_root,rvm_true))
1132 return retval;
1133
1134 /* check each segment descriptor */
1135 FOR_ENTRIES_OF(log_root,log_t,log)
1136 {
1137 i++;
1138 if (in_log(addr,log,i)) retval = rvm_true;
1139 }
1140
1141 return retval;
1142 }
1143 /* locate an address in RVM internal structures */
find_addr(addr)1144 void find_addr(addr)
1145 rvm_length_t addr; /* address to search for */
1146 {
1147 rvm_bool_t retval = rvm_false;
1148
1149 if (in_free_page_list(addr))
1150 retval = rvm_true;
1151 if (in_free_lists(addr))
1152 retval = rvm_true;
1153 if (in_region_tree(addr))
1154 retval = rvm_true;
1155 if (in_seg_list(addr))
1156 retval = rvm_true;
1157 if (in_log_list(addr))
1158 retval = rvm_true;
1159
1160 if (!retval)
1161 printf("\nAddress not found\n");
1162
1163 }
1164 /* test if entry is on list -- more forgiving than chk_list */
on_list(hdr,addr)1165 void on_list(hdr,addr)
1166 list_entry_t *hdr; /* header of list to search */
1167 list_entry_t *addr; /* entry to search for */
1168 {
1169 list_entry_t *entry; /* current list entry */
1170 long i = 0;
1171
1172 if (hdr == NULL)
1173 {
1174 printf("List header is null\n"); return;
1175 }
1176 if (ADDR_INVALID(hdr))
1177 {
1178 printf("List header address invalid\n"); return;
1179 }
1180 if (hdr->is_hdr != rvm_true)
1181 {
1182 printf("List header invalid\n"); return;
1183 }
1184 if (addr == hdr)
1185 {
1186 printf("Entry is list header\n"); return;
1187 }
1188
1189 if (addr == NULL)
1190 {
1191 printf("Entry is null\n"); return;
1192 }
1193 if (ADDR_INVALID(addr))
1194 {
1195 printf("Entry address invalid\n"); return;
1196 }
1197 if (addr->is_hdr)
1198 printf("Entry claims to be a list header\n");
1199
1200 if (!(((long)hdr->struct_id > (long)struct_first_id) &&
1201 ((long)hdr->struct_id < (long)struct_last_id)))
1202 printf(" List header type is not valid, struct_id = %ld\n",
1203 (long)hdr->struct_id);
1204 if (!(((long)addr->struct_id > (long)struct_first_id) &&
1205 ((long)addr->struct_id < (long)struct_last_id)))
1206 printf(" Entry type is not valid, struct_id = %ld\n",
1207 (long)addr->struct_id);
1208 if (hdr->struct_id != addr->struct_id) {
1209 printf("Entry is not of same type as list -- \n");
1210 printf(" Entry->struct_id = %ld\n",(long)addr->struct_id);
1211 printf(" Header->struct_id = %ld\n",(long)hdr->struct_id);
1212 }
1213 if (addr->list.name != hdr)
1214 printf("Entry claims to be on list %lx\n",(long)addr->list.name);
1215
1216 if (ADDR_INVALID_OR_NULL(hdr->nextentry))
1217 {
1218 printf(" List header has invalid nextentry field, ");
1219 printf("hdr->nextentry = %lx\n",(long)hdr->nextentry);
1220 return;
1221 }
1222 if (ADDR_INVALID_OR_NULL(hdr->preventry)) {
1223 printf(" List header has invalid preventry field, ");
1224 printf("hdr->preventry = %lx\n",(long)hdr->nextentry);
1225 }
1226
1227 /* check all elements of list */
1228 entry = hdr->nextentry;
1229 while (entry->is_hdr != rvm_true)
1230 {
1231 i++;
1232 if (entry == addr)
1233 {
1234 printf("Entry is number %ld of list\n",i);
1235 return;
1236 }
1237 if (ADDR_INVALID_OR_NULL(entry->nextentry))
1238 {
1239 printf("Entry %ld has invalid nextentry field, ",i);
1240 printf("nextentry = %lx\n",(long)entry->nextentry);
1241 return;
1242 }
1243 entry = entry->nextentry;
1244 }
1245
1246 printf("Entry not on list\n");
1247 }
1248 #endif /* DEBUG_GDB */
1249