static void MR_debug_zone_extend(FILE *fp, const char *when, const char *stackname, MR_MemoryZone *zone) { fprintf(fp, "----------------\n"); fprintf(fp, "%s extending %s\n\n", when, stackname); MR_debug_memory_zone(fp, zone); }
MR_bool MR_default_handler(MR_Word *fault_addr, MR_MemoryZone *zone, void *context) { #ifndef MR_CHECK_OVERFLOW_VIA_MPROTECT return MR_FALSE; #else MR_Word *new_zone; size_t zone_size; new_zone = (MR_Word *) MR_round_up((MR_Unsigned) fault_addr + sizeof(MR_Word), MR_unit); if (new_zone <= zone->MR_zone_hardmax) { zone_size = (char *) new_zone - (char *) zone->MR_zone_redzone; if (MR_memdebug) { fprintf(stderr, "trying to unprotect %s#%" MR_INTEGER_LENGTH_MODIFIER "d from %p to %p (%x)\n", zone->MR_zone_name, zone->MR_zone_id, (void *) zone->MR_zone_redzone, (void *) new_zone, (int) zone_size); } if (MR_protect_pages((char *) zone->MR_zone_redzone, zone_size, PROT_READ|PROT_WRITE) < 0) { char buf[2560]; sprintf(buf, "Mercury runtime: cannot unprotect %s#%" MR_INTEGER_LENGTH_MODIFIER "d zone", zone->MR_zone_name, zone->MR_zone_id); perror(buf); exit(1); } zone->MR_zone_redzone = new_zone; if (MR_memdebug) { fprintf(stderr, "successful: %s#%" MR_INTEGER_LENGTH_MODIFIER "d redzone now %p to %p\n", zone->MR_zone_name, zone->MR_zone_id, (void *) zone->MR_zone_redzone, (void *) zone->MR_zone_top); } #if defined(MR_NATIVE_GC) && !defined(MR_HIGHLEVEL_CODE) MR_schedule_agc(get_pc_from_context(context), get_sp_from_context(context), get_curfr_from_context(context)); #endif return MR_TRUE; } else { char buf[2560]; if (MR_memdebug) { fprintf(stderr, "can't unprotect last page of %s#%" MR_INTEGER_LENGTH_MODIFIER "d\n", zone->MR_zone_name, zone->MR_zone_id); fflush(stdout); } #ifdef MR_STACK_EXTEND_DEBUG MR_restore_transient_registers(); fprintf(stderr, "sp = %p, maxfr = %p\n", MR_sp, MR_maxfr); MR_debug_memory_zone(stderr, zone); #endif sprintf(buf, "\nMercury runtime: memory zone %s#%" MR_INTEGER_LENGTH_MODIFIER "d overflowed\n", zone->MR_zone_name, zone->MR_zone_id); MR_fatal_abort(context, buf, MR_TRUE); } return MR_FALSE; #endif }