1#!/usr/bin/env python 2#===- lib/fuzzer/scripts/unbalanced_allocs.py ------------------------------===# 3# 4# The LLVM Compiler Infrastructure 5# 6# This file is distributed under the University of Illinois Open Source 7# License. See LICENSE.TXT for details. 8# 9#===------------------------------------------------------------------------===# 10# 11# Post-process -trace_malloc=2 output and printout only allocations and frees 12# unbalanced inside of fuzzer runs. 13# Usage: 14# my_fuzzer -trace_malloc=2 -runs=10 2>&1 | unbalanced_allocs.py -skip=5 15# 16#===------------------------------------------------------------------------===# 17 18import argparse 19import sys 20 21_skip = 0 22 23def PrintStack(line, stack): 24 global _skip 25 if _skip > 0: 26 return 27 print('Unbalanced ' + line.rstrip()); 28 for l in stack: 29 print(l.rstrip()) 30 31def ProcessStack(line, f): 32 stack = [] 33 while line and line.startswith(' #'): 34 stack += [line] 35 line = f.readline() 36 return line, stack 37 38def ProcessFree(line, f, allocs): 39 if not line.startswith('FREE['): 40 return f.readline() 41 42 addr = int(line.split()[1], 16) 43 next_line, stack = ProcessStack(f.readline(), f) 44 if addr in allocs: 45 del allocs[addr] 46 else: 47 PrintStack(line, stack) 48 return next_line 49 50def ProcessMalloc(line, f, allocs): 51 if not line.startswith('MALLOC['): 52 return ProcessFree(line, f, allocs) 53 54 addr = int(line.split()[1], 16) 55 assert not addr in allocs 56 57 next_line, stack = ProcessStack(f.readline(), f) 58 allocs[addr] = (line, stack) 59 return next_line 60 61def ProcessRun(line, f): 62 if not line.startswith('MallocFreeTracer: START'): 63 return ProcessMalloc(line, f, {}) 64 65 allocs = {} 66 print(line.rstrip()) 67 line = f.readline() 68 while line: 69 if line.startswith('MallocFreeTracer: STOP'): 70 global _skip 71 _skip = _skip - 1 72 for _, (l, s) in allocs.items(): 73 PrintStack(l, s) 74 print(line.rstrip()) 75 return f.readline() 76 line = ProcessMalloc(line, f, allocs) 77 return line 78 79def ProcessFile(f): 80 line = f.readline() 81 while line: 82 line = ProcessRun(line, f); 83 84def main(argv): 85 parser = argparse.ArgumentParser() 86 parser.add_argument('--skip', default=0, help='number of runs to ignore') 87 args = parser.parse_args() 88 global _skip 89 _skip = int(args.skip) + 1 90 ProcessFile(sys.stdin) 91 92if __name__ == '__main__': 93 main(sys.argv) 94