check_heap.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. /*
  2. * Part of Scheme 48 1.9. See file COPYING for notices and license.
  3. *
  4. * Authors: David Frese, Mike Sperber
  5. */
  6. #include <stdlib.h>
  7. #include <stdio.h>
  8. #include "scheme48.h"
  9. #include "generation_gc.h"
  10. #include "utils.h"
  11. #include "data.h"
  12. #include "memory.h"
  13. #include "memory_map.h"
  14. /* how many errors are left before program termination */
  15. static long errors_left;
  16. char s48_stob_in_heapP(s48_value stob) {
  17. s48_address addr = S48_ADDRESS_AT_HEADER(stob);
  18. Area* area = s48_memory_map_ref(addr);
  19. return ((area != NULL) && (area->start <= addr) && (addr < area->frontier));
  20. }
  21. static void error_found(char* message) {
  22. fprintf(stderr, "check heap: %s\n", message);
  23. if (errors_left == 0) {
  24. s48_gc_error("check heap: too many errors!");
  25. } else {
  26. errors_left--;
  27. }
  28. }
  29. static void try_describe_area_at(s48_address addr) {
  30. Area* a = s48_memory_map_ref(addr);
  31. fprintf(stderr, "Area containing 0x%p", addr);
  32. if (a != NULL) {
  33. fprintf(stderr, "\n 0x%p-[0x%p]-0x%p\n", a->start, a->frontier, a->end);
  34. fprintf(stderr, " generation: %d\n", a->generation_index);
  35. fprintf(stderr, " type: %d\n", a->area_type_size);
  36. fprintf(stderr, " %s last in chain\n", a->next ? "not" : "");
  37. }
  38. else
  39. fprintf(stderr, " could not be found\n");
  40. }
  41. static void check_area(s48_address start, s48_address end) {
  42. s48_address addr = start;
  43. while (addr < end) {
  44. long header = *((long*)addr);
  45. if (!S48_HEADER_P(header)) {
  46. char s[512];
  47. try_describe_area_at(addr);
  48. sprintf(s, "corrupted header 0x%lX at 0x%p!", header, addr);
  49. error_found(s);
  50. addr = S48_ADDRESS_INC(addr);
  51. } else {
  52. s48_address next = addr + S48_STOB_OVERHEAD_IN_A_UNITS
  53. + S48_HEADER_LENGTH_IN_A_UNITS(header);
  54. if (!S48_B_VECTOR_HEADER_P(header)) {
  55. s48_value v; int i;
  56. int len = S48_HEADER_LENGTH_IN_CELLS(header);
  57. s48_value* this_addr = ((s48_value*)addr); /* increased in the first loop */
  58. for (i = 0; i < len; i++) {
  59. this_addr++;
  60. v = *this_addr;
  61. if ( S48_HEADER_P(v) ) {
  62. char s[512];
  63. sprintf(s, "content value 0x%lX at 0x%p is a header!",
  64. v, this_addr);
  65. error_found(s);
  66. } else if ( S48_STOB_P(v) && (!s48_stob_in_heapP(v)) ) {
  67. char s[512];
  68. sprintf(s, "stob value 0x%lX in object of type %ld at 0x%p pointing outside the heap!", v, S48_HEADER_TYPE(header), this_addr);
  69. error_found(s);
  70. }
  71. }
  72. }
  73. addr = next;
  74. }
  75. }
  76. }
  77. /* error_count : maximal errors allowed */
  78. char s48_check_heap(long error_count) {
  79. errors_left = error_count;
  80. s48_walk_heap(&check_area);
  81. /* If errors_left ist not decremented
  82. means there was no error => s48_check_heap = TRUE */
  83. return (errors_left == error_count);
  84. }