void FreeTrackData::LogBacktrace(const Header* header) { ScopedDisableDebugCalls disable; auto back_iter = backtraces_.find(header); if (back_iter == backtraces_.end()) { return; } error_log("Backtrace of original free:"); backtrace_log(&back_iter->second->frames[0], back_iter->second->num_frames); }
static void LogTagError(const Header* header, const void* pointer, const char* name) { error_log(LOG_DIVIDER); if (header->tag == DEBUG_FREE_TAG) { error_log("+++ ALLOCATION %p USED AFTER FREE (%s)", pointer, name); if (g_debug->config().options & FREE_TRACK) { g_debug->free_track->LogBacktrace(header); } } else { error_log("+++ ALLOCATION %p HAS INVALID TAG %" PRIx32 " (%s)", pointer, header->tag, name); } error_log("Backtrace at time of failure:"); std::vector<uintptr_t> frames(64); size_t frame_num = backtrace_get(frames.data(), frames.size()); frames.resize(frame_num); backtrace_log(frames.data(), frames.size()); error_log(LOG_DIVIDER); }
void FreeTrackData::LogFreeError(DebugData& debug, const Header* header, const uint8_t* pointer) { ScopedDisableDebugCalls disable; error_log(LOG_DIVIDER); error_log("+++ ALLOCATION %p USED AFTER FREE", pointer); uint8_t fill_free_value = debug.config().fill_free_value; for (size_t i = 0; i < header->usable_size; i++) { if (pointer[i] != fill_free_value) { error_log(" pointer[%zu] = 0x%02x (expected 0x%02x)", i, pointer[i], fill_free_value); } } auto back_iter = backtraces_.find(header); if (back_iter != backtraces_.end()) { const BacktraceHeader* back_header = back_iter->second; error_log("Backtrace at time of free:"); backtrace_log(&back_header->frames[0], back_header->num_frames); } error_log(LOG_DIVIDER); }
void GuardData::LogFailure(const Header* header, const void* pointer, const void* data) { ScopedDisableDebugCalls disable; error_log(LOG_DIVIDER); error_log("+++ ALLOCATION %p SIZE %zu HAS A CORRUPTED %s GUARD", pointer, header->real_size(), GetTypeName()); // Log all of the failing bytes. const uint8_t* expected = cmp_mem_.data(); int pointer_idx = reinterpret_cast<uintptr_t>(data) - reinterpret_cast<uintptr_t>(pointer); const uint8_t* real = reinterpret_cast<const uint8_t*>(data); for (size_t i = 0; i < cmp_mem_.size(); i++, pointer_idx++) { if (real[i] != expected[i]) { error_log(" pointer[%d] = 0x%02x (expected 0x%02x)", pointer_idx, real[i], expected[i]); } } error_log("Backtrace at time of failure:"); std::vector<uintptr_t> frames(64); size_t frame_num = backtrace_get(frames.data(), frames.size()); frames.resize(frame_num); backtrace_log(frames.data(), frames.size()); error_log(LOG_DIVIDER); }