101 lines · python
1#!/usr/bin/env python2# ===- lib/fuzzer/scripts/unbalanced_allocs.py ------------------------------===#3#4# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.5# See https://llvm.org/LICENSE.txt for license information.6# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception7#8# ===------------------------------------------------------------------------===#9#10# Post-process -trace_malloc=2 output and printout only allocations and frees11# unbalanced inside of fuzzer runs.12# Usage:13# my_fuzzer -trace_malloc=2 -runs=10 2>&1 | unbalanced_allocs.py -skip=514#15# ===------------------------------------------------------------------------===#16 17import argparse18import sys19 20_skip = 021 22 23def PrintStack(line, stack):24 global _skip25 if _skip > 0:26 return27 print("Unbalanced " + line.rstrip())28 for l in stack:29 print(l.rstrip())30 31 32def ProcessStack(line, f):33 stack = []34 while line and line.startswith(" #"):35 stack += [line]36 line = f.readline()37 return line, stack38 39 40def ProcessFree(line, f, allocs):41 if not line.startswith("FREE["):42 return f.readline()43 44 addr = int(line.split()[1], 16)45 next_line, stack = ProcessStack(f.readline(), f)46 if addr in allocs:47 del allocs[addr]48 else:49 PrintStack(line, stack)50 return next_line51 52 53def ProcessMalloc(line, f, allocs):54 if not line.startswith("MALLOC["):55 return ProcessFree(line, f, allocs)56 57 addr = int(line.split()[1], 16)58 assert not addr in allocs59 60 next_line, stack = ProcessStack(f.readline(), f)61 allocs[addr] = (line, stack)62 return next_line63 64 65def ProcessRun(line, f):66 if not line.startswith("MallocFreeTracer: START"):67 return ProcessMalloc(line, f, {})68 69 allocs = {}70 print(line.rstrip())71 line = f.readline()72 while line:73 if line.startswith("MallocFreeTracer: STOP"):74 global _skip75 _skip = _skip - 176 for _, (l, s) in allocs.items():77 PrintStack(l, s)78 print(line.rstrip())79 return f.readline()80 line = ProcessMalloc(line, f, allocs)81 return line82 83 84def ProcessFile(f):85 line = f.readline()86 while line:87 line = ProcessRun(line, f)88 89 90def main(argv):91 parser = argparse.ArgumentParser()92 parser.add_argument("--skip", default=0, help="number of runs to ignore")93 args = parser.parse_args()94 global _skip95 _skip = int(args.skip) + 196 ProcessFile(sys.stdin)97 98 99if __name__ == "__main__":100 main(sys.argv)101