123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293 |
- /*
- * Part of Scheme 48 1.9. See file COPYING for notices and license.
- *
- * Authors: David Frese, Mike Sperber
- */
- #include <stdlib.h>
- #include <stdio.h>
- #include "scheme48.h"
- #include "generation_gc.h"
- #include "utils.h"
- #include "data.h"
- #include "memory.h"
- #include "memory_map.h"
- /* how many errors are left before program termination */
- static long errors_left;
- char s48_stob_in_heapP(s48_value stob) {
- s48_address addr = S48_ADDRESS_AT_HEADER(stob);
- Area* area = s48_memory_map_ref(addr);
- return ((area != NULL) && (area->start <= addr) && (addr < area->frontier));
- }
- static void error_found(char* message) {
- fprintf(stderr, "check heap: %s\n", message);
- if (errors_left == 0) {
- s48_gc_error("check heap: too many errors!");
- } else {
- errors_left--;
- }
- }
- static void try_describe_area_at(s48_address addr) {
- Area* a = s48_memory_map_ref(addr);
- fprintf(stderr, "Area containing 0x%p", addr);
- if (a != NULL) {
- fprintf(stderr, "\n 0x%p-[0x%p]-0x%p\n", a->start, a->frontier, a->end);
- fprintf(stderr, " generation: %d\n", a->generation_index);
- fprintf(stderr, " type: %d\n", a->area_type_size);
- fprintf(stderr, " %s last in chain\n", a->next ? "not" : "");
- }
- else
- fprintf(stderr, " could not be found\n");
- }
- static void check_area(s48_address start, s48_address end) {
- s48_address addr = start;
- while (addr < end) {
- long header = *((long*)addr);
- if (!S48_HEADER_P(header)) {
- char s[512];
- try_describe_area_at(addr);
- sprintf(s, "corrupted header 0x%lX at 0x%p!", header, addr);
- error_found(s);
- addr = S48_ADDRESS_INC(addr);
- } else {
- s48_address next = addr + S48_STOB_OVERHEAD_IN_A_UNITS
- + S48_HEADER_LENGTH_IN_A_UNITS(header);
- if (!S48_B_VECTOR_HEADER_P(header)) {
- s48_value v; int i;
- int len = S48_HEADER_LENGTH_IN_CELLS(header);
- s48_value* this_addr = ((s48_value*)addr); /* increased in the first loop */
- for (i = 0; i < len; i++) {
- this_addr++;
- v = *this_addr;
- if ( S48_HEADER_P(v) ) {
- char s[512];
- sprintf(s, "content value 0x%lX at 0x%p is a header!",
- v, this_addr);
- error_found(s);
- } else if ( S48_STOB_P(v) && (!s48_stob_in_heapP(v)) ) {
- char s[512];
- 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);
- error_found(s);
- }
- }
- }
- addr = next;
- }
- }
- }
- /* error_count : maximal errors allowed */
- char s48_check_heap(long error_count) {
- errors_left = error_count;
- s48_walk_heap(&check_area);
- /* If errors_left ist not decremented
- means there was no error => s48_check_heap = TRUE */
- return (errors_left == error_count);
- }
|