1ca907527SVitaly Buka#!/usr/bin/env python 2ca907527SVitaly Buka# ===- lib/fuzzer/scripts/unbalanced_allocs.py ------------------------------===# 3ca907527SVitaly Buka# 42946cd70SChandler Carruth# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 52946cd70SChandler Carruth# See https://llvm.org/LICENSE.txt for license information. 62946cd70SChandler Carruth# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7ca907527SVitaly Buka# 8ca907527SVitaly Buka# ===------------------------------------------------------------------------===# 9ca907527SVitaly Buka# 10ca907527SVitaly Buka# Post-process -trace_malloc=2 output and printout only allocations and frees 11ca907527SVitaly Buka# unbalanced inside of fuzzer runs. 12ca907527SVitaly Buka# Usage: 13ca907527SVitaly Buka# my_fuzzer -trace_malloc=2 -runs=10 2>&1 | unbalanced_allocs.py -skip=5 14ca907527SVitaly Buka# 15ca907527SVitaly Buka# ===------------------------------------------------------------------------===# 16ca907527SVitaly Buka 17ca907527SVitaly Bukaimport argparse 18ca907527SVitaly Bukaimport sys 19ca907527SVitaly Buka 20ca907527SVitaly Buka_skip = 0 21ca907527SVitaly Buka 22*f98ee40fSTobias Hieta 23ca907527SVitaly Bukadef PrintStack(line, stack): 24ca907527SVitaly Buka global _skip 25ca907527SVitaly Buka if _skip > 0: 26ca907527SVitaly Buka return 27*f98ee40fSTobias Hieta print("Unbalanced " + line.rstrip()) 28ca907527SVitaly Buka for l in stack: 29c8879c98SDan Liew print(l.rstrip()) 30ca907527SVitaly Buka 31*f98ee40fSTobias Hieta 32ca907527SVitaly Bukadef ProcessStack(line, f): 33ca907527SVitaly Buka stack = [] 34*f98ee40fSTobias Hieta while line and line.startswith(" #"): 35ca907527SVitaly Buka stack += [line] 36ca907527SVitaly Buka line = f.readline() 37ca907527SVitaly Buka return line, stack 38ca907527SVitaly Buka 39*f98ee40fSTobias Hieta 40ca907527SVitaly Bukadef ProcessFree(line, f, allocs): 41*f98ee40fSTobias Hieta if not line.startswith("FREE["): 42ca907527SVitaly Buka return f.readline() 43ca907527SVitaly Buka 44ca907527SVitaly Buka addr = int(line.split()[1], 16) 45ca907527SVitaly Buka next_line, stack = ProcessStack(f.readline(), f) 46ca907527SVitaly Buka if addr in allocs: 47ca907527SVitaly Buka del allocs[addr] 48ca907527SVitaly Buka else: 49ca907527SVitaly Buka PrintStack(line, stack) 50ca907527SVitaly Buka return next_line 51ca907527SVitaly Buka 52*f98ee40fSTobias Hieta 53ca907527SVitaly Bukadef ProcessMalloc(line, f, allocs): 54*f98ee40fSTobias Hieta if not line.startswith("MALLOC["): 55ca907527SVitaly Buka return ProcessFree(line, f, allocs) 56ca907527SVitaly Buka 57ca907527SVitaly Buka addr = int(line.split()[1], 16) 58ca907527SVitaly Buka assert not addr in allocs 59ca907527SVitaly Buka 60ca907527SVitaly Buka next_line, stack = ProcessStack(f.readline(), f) 61ca907527SVitaly Buka allocs[addr] = (line, stack) 62ca907527SVitaly Buka return next_line 63ca907527SVitaly Buka 64*f98ee40fSTobias Hieta 65ca907527SVitaly Bukadef ProcessRun(line, f): 66*f98ee40fSTobias Hieta if not line.startswith("MallocFreeTracer: START"): 67ca907527SVitaly Buka return ProcessMalloc(line, f, {}) 68ca907527SVitaly Buka 69ca907527SVitaly Buka allocs = {} 70c8879c98SDan Liew print(line.rstrip()) 71ca907527SVitaly Buka line = f.readline() 72ca907527SVitaly Buka while line: 73*f98ee40fSTobias Hieta if line.startswith("MallocFreeTracer: STOP"): 74ca907527SVitaly Buka global _skip 75ca907527SVitaly Buka _skip = _skip - 1 76c8879c98SDan Liew for _, (l, s) in allocs.items(): 77ca907527SVitaly Buka PrintStack(l, s) 78c8879c98SDan Liew print(line.rstrip()) 79ca907527SVitaly Buka return f.readline() 80ca907527SVitaly Buka line = ProcessMalloc(line, f, allocs) 81ca907527SVitaly Buka return line 82ca907527SVitaly Buka 83*f98ee40fSTobias Hieta 84ca907527SVitaly Bukadef ProcessFile(f): 85ca907527SVitaly Buka line = f.readline() 86ca907527SVitaly Buka while line: 87*f98ee40fSTobias Hieta line = ProcessRun(line, f) 88*f98ee40fSTobias Hieta 89ca907527SVitaly Buka 90ca907527SVitaly Bukadef main(argv): 91ca907527SVitaly Buka parser = argparse.ArgumentParser() 92*f98ee40fSTobias Hieta parser.add_argument("--skip", default=0, help="number of runs to ignore") 93ca907527SVitaly Buka args = parser.parse_args() 94ca907527SVitaly Buka global _skip 95ca907527SVitaly Buka _skip = int(args.skip) + 1 96ca907527SVitaly Buka ProcessFile(sys.stdin) 97ca907527SVitaly Buka 98*f98ee40fSTobias Hieta 99*f98ee40fSTobias Hietaif __name__ == "__main__": 100ca907527SVitaly Buka main(sys.argv) 101