From 3cdc8fa128e382136a2398c99c97de96d806c146 Mon Sep 17 00:00:00 2001 From: Roman Gershman Date: Tue, 10 Sep 2024 10:26:44 +0300 Subject: [PATCH] chore: add a script that parses allocator tracking logs (#3687) --- src/core/allocation_tracker.cc | 3 +- tools/parse_allocator_tracking_logs.py | 45 ++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) create mode 100755 tools/parse_allocator_tracking_logs.py diff --git a/src/core/allocation_tracker.cc b/src/core/allocation_tracker.cc index 7b65c3b22..42b64cecc 100644 --- a/src/core/allocation_tracker.cc +++ b/src/core/allocation_tracker.cc @@ -85,7 +85,8 @@ void AllocationTracker::ProcessDelete(void* ptr) { if (tracking_.size() == 1 && tracking_.front().sample_odds == 1) { size_t usable = mi_usable_size(ptr); if (usable <= tracking_.front().upper_bound && usable >= tracking_.front().lower_bound) { - LOG(INFO) << "Deallocating " << usable << " bytes (" << ptr << ")"; + LOG(INFO) << "Deallocating " << usable << " bytes (" << ptr << ")\n" + << util::fb2::GetStacktrace(); } } inside_tracker_ = false; diff --git a/tools/parse_allocator_tracking_logs.py b/tools/parse_allocator_tracking_logs.py new file mode 100755 index 000000000..f10525134 --- /dev/null +++ b/tools/parse_allocator_tracking_logs.py @@ -0,0 +1,45 @@ +#!/usr/bin/env python3 + +""" +Usage: +1. First run Dragonfly with tracking allocator enabled. Must be a single allocator range with 100% samping rate to catch both allocations and deallocations. +2. Finish tracking. +3. cat /tmp/dragonfly.INFO | ./parse_allocator_tracking_logs.py +""" +import re +import sys + + +def parse_log(log_lines): + memory_map = {} + + allocation_pattern = re.compile(r"Allocating (\d+) bytes \((0x[0-9a-f]+)\)") + deallocation_pattern = re.compile(r"Deallocating (\d+) bytes \((0x[0-9a-f]+)\)") + + for line in log_lines: + allocation_match = allocation_pattern.search(line) + deallocation_match = deallocation_pattern.search(line) + + if allocation_match: + size = int(allocation_match.group(1)) + address = allocation_match.group(2) + assert address not in memory_map + memory_map[address] = (size, line) + elif deallocation_match: + size = int(deallocation_match.group(1)) + address = deallocation_match.group(2) + if address in memory_map: + assert size == memory_map[address][0] + del memory_map[address] + else: + print(f"Deallocating non existing address: {address} {size}") + + return memory_map + + +if __name__ == "__main__": + log_lines = sys.stdin.readlines() + memory_map = parse_log(log_lines) + + for address, item in memory_map.items(): + print(f"Address: {address}, Size: {item[0]} bytes, original line: `{item[1]}`")