VOID ReallocAfter(ADDRINT mallocStartAddr, THREADID tid) { ThreadLocalStorage* tls = getTLS(tid); ADDRINT previousAddress = tls->nextReallocAddr; ADDRINT newSize = tls->nextReallocSize; //if previous address is NULL, this is the same as malloc if (previousAddress == 0) { tls->nextMallocSize = tls->nextReallocSize; tls->nextReallocAddr = 0; tls->nextReallocSize = 0; MallocAfter(mallocStartAddr, tid); return; } const MemoryArea& prevArea = findMemoryArea(mallocStartAddr); MemoryArea newArea(tid, mallocStartAddr, mallocStartAddr + newSize); ADDRINT prevSize = prevArea.to - prevArea.from; // Realloc gives the same address as previos realloc(or malloc,calloc) if (prevArea.from == mallocStartAddr) { //eger yeni yer daha kucuk ise, eskiden bizim olan aradaki yerleri free edelim if (newSize < prevSize) { freeMemoryAddress(mallocStartAddr + newSize, mallocStartAddr + prevSize, tid); } } else { if (newSize < prevSize) { moveMemoryAddresses(previousAddress, mallocStartAddr, newSize, tid); freeMemoryAddress(previousAddress + newSize, previousAddress + prevSize, tid); } else { moveMemoryAddresses(previousAddress, mallocStartAddr, prevSize, tid); freeMemoryAddress(previousAddress, previousAddress + prevSize, tid); } } GetLock(&memorySetLock, tid); memorySet.insert(newArea); memorySet.erase(prevArea); ReleaseLock(&memorySetLock); }
VOID FreeEnter(ADDRINT startAddress, THREADID threadid) { GetLock(&memorySetLock, threadid); const MemoryArea area = findMemoryArea(startAddress); ADDRINT freeSize = area.size(); memorySet.erase(area); ReleaseLock(&memorySetLock); if (freeSize == 0) return; freeMemoryAddress(startAddress, area.to, threadid); }
void TraceData::parseReport(const std::string& filename) { release(); std::ifstream file; std::istream& in = filename.empty() ? std::cin : file; if (!filename.empty()) { file.open(filename.c_str(), std::ios_base::in); if (file.fail()) { throw std::ios_base::failure(Formatter() << "Failed to open file: " << filename); } } char buffer[4096]; in.getline(buffer, sizeof(buffer)); if (in.eof()) throw std::runtime_error(Formatter() << "Empty input file: " << filename); if (buffer[0] == (char)SP_RTRACE_PROTO_HS_ID) { throw std::runtime_error("Can't process sp-rtrace binary files. " "Convert to text format with sp-rtrace-postproc and try again."); } sp_rtrace_parser_parse_header(buffer, &header); while (true && (filename_maps.empty() || filename_pageflags.empty()) ) { in.getline(buffer, sizeof(buffer)); if (in.eof()) break; sp_rtrace_record_t rec; int rec_type = sp_rtrace_parser_parse_record(buffer, &rec); switch (rec_type) { case SP_RTRACE_RECORD_ATTACHMENT: if (!strcmp(rec.attachment.name, ATTACHMENT_MAPS)) filename_maps = rec.attachment.path; else if (!strcmp(rec.attachment.name, ATTACHMENT_PAGEFLAGS)) filename_pageflags = rec.attachment.path; break; } sp_rtrace_parser_free_record(rec_type, &rec); } if (access(filename_maps.c_str(), F_OK) == -1) throw std::runtime_error(Formatter() << "Failed to access maps file '" << filename_maps << "': " << strerror(errno)); if (access(filename_pageflags.c_str(), F_OK) == -1) throw std::runtime_error(Formatter() << "Failed to access pageflags file '" << filename_pageflags << "': " << strerror(errno)); // map the pageflags file to memory pageflags_fd = open(filename_pageflags.c_str(), O_RDONLY); if (pageflags_fd == -1) throw std::runtime_error(Formatter() << "Failed to open pageflags file '" << filename_pageflags << "': " << strerror(errno)); struct stat ps; if (fstat(pageflags_fd, &ps) == -1) throw std::runtime_error(Formatter() << "Failed to stat pageflags file '" << filename_pageflags << "': " << strerror(errno)); pageflags_size = ps.st_size; pageflags_addr = mmap(NULL, pageflags_size, PROT_READ, MAP_SHARED, pageflags_fd, 0); if (pageflags_addr == MAP_FAILED) throw std::runtime_error(Formatter() << "Failed to mmap pageflags file '" << filename_pageflags << "': " << strerror(errno)); // scan the mapped areas from maps/pageflags files scanMemoryAreas(); // scan the allocation events in.seekg(0); std::list<CallEvent*> last_events; sp_rtrace_btframe_t frames[512]; sp_rtrace_btframe_t* pframe = frames; while (true) { in.getline(buffer, sizeof(buffer)); if (in.eof()) break; sp_rtrace_record_t rec; int rec_type = sp_rtrace_parser_parse_record(buffer, &rec); if (rec_type == SP_RTRACE_RECORD_TRACE) { /* don't collect backtrace records if there is no preceeding allocation * function event */ if (last_events.empty()) { sp_rtrace_parser_free_record(rec_type, &rec); } else { *pframe++ = rec.frame; } continue; } // Store backtrace record for last cached events if ((pframe > frames || !*buffer) && !last_events.empty()) { storeTrace(last_events, frames, pframe - frames); last_events.clear(); } if (rec_type == SP_RTRACE_RECORD_CALL) { if (rec.call.type == SP_RTRACE_FTYPE_ALLOC) { MemoryArea* area = findMemoryArea(rec.call.res_id); if (area) { last_events.push_back(area->addEvent(rec.call)); continue; } } } pframe = frames; sp_rtrace_parser_free_record(rec_type, &rec); } if ((pframe > frames || !*buffer) && !last_events.empty()) { fprintf(stderr, "last parse\n"); storeTrace(last_events, frames, pframe - frames); last_events.clear(); } // sort the allocation events inside areas for (MemoryArea::vector_t::iterator iter = memory_areas.begin(); iter != memory_areas.end(); iter++) { iter->get()->sortEvents(); } }