/* Perform binary difference on all monitored ranges */ void check_monitored_ranges() { /* incremental update */ for(MemIntervalSet::const_iterator i=persistent.begin(); i!=persistent.end(); ++i) { /* Check whether range is already stored */ FlightRecStorage::iterator j = stored.find(*i); if(j == stored.end()) { /* Not in storage at all, write whole block. */ //printf("Not in storage at all, write whole block.\n"); write_mem_range(i->start, i->end); /* Copy memory block to newly allocated storage, * so that we can compare against it later. */ void *block = malloc(i->end - i->start); memcpy(block, (void*)i->start, i->end - i->start); stored.insert(std::make_pair(*i, block)); } else { if(j->first.start != i->start || j->first.end != i->end) { /* Huh? Not exactly the same range, could do an intersection here but * currently this is not supported, write the entire range */ //printf("Warning: stored block mismatch start1=%p start2=%p end1=%p end2=%p\n", j->first.start, i->start, j->first.end, i->end); write_mem_range(i->start, i->end); } else { /* compare ranges and write differences */ /* copy new values to storage */ bdiff((size_t)j->second, i->start, i->end - i->start, diff_granularity); memcpy(j->second, (void*)i->start, i->end - i->start); } } } }
flightrec_status add_oneshot_range(size_t addr_start, size_t addr_end) { MemInterval r(addr_start, addr_end); flightrec_status ret = FDR_OK; std::pair<MemIntervalSet::iterator, bool> rv = temp.insert(MemInterval(addr_start, addr_end)); if(!rv.second) { /* overlaps with already existing temporary range; bounce it */ ret = FDR_OVERLAP; } return ret; }
flightrec_status add_monitored_range(size_t addr_start, size_t addr_end) { pthread_mutex_lock(&mutex); std::pair<MemIntervalSet::iterator, bool> rv = persistent.insert(MemInterval(addr_start, addr_end)); if(rv.second) { write_record_type(fd, RTYPE_ADD_UPDATED_RANGE); write(fd, &addr_start, sizeof(size_t)); write(fd, &addr_end, sizeof(size_t)); } pthread_mutex_unlock(&mutex); return rv.second ? FDR_OK : FDR_OVERLAP; }
flightrec_status remove_monitored_range(size_t addr_start, size_t addr_end) { pthread_mutex_lock(&mutex); // XXX currently assumes a complete match, partial munmaps are not supported size_t ret = persistent.erase(MemInterval(addr_start, addr_end)); if(ret) { write_record_type(fd, RTYPE_REMOVE_UPDATED_RANGE); (void)write(fd, &addr_start, sizeof(size_t)); (void)write(fd, &addr_end, sizeof(size_t)); } pthread_mutex_unlock(&mutex); return ret ? FDR_OK : FDR_NOT_FOUND; }