blob: 579e481a237ac76835b0e57cc595d711f6222cdf [file] [log] [blame]
vitalybuka0239a5b2017-11-01 20:27:06 +00001#!/usr/bin/env python
2#===- lib/fuzzer/scripts/unbalanced_allocs.py ------------------------------===#
3#
chandlerc40284492019-01-19 08:50:56 +00004# 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-exception
vitalybuka0239a5b2017-11-01 20:27:06 +00007#
8#===------------------------------------------------------------------------===#
9#
10# Post-process -trace_malloc=2 output and printout only allocations and frees
11# unbalanced inside of fuzzer runs.
12# Usage:
13# my_fuzzer -trace_malloc=2 -runs=10 2>&1 | unbalanced_allocs.py -skip=5
14#
15#===------------------------------------------------------------------------===#
16
17import argparse
18import sys
19
20_skip = 0
21
22def PrintStack(line, stack):
23 global _skip
24 if _skip > 0:
25 return
delcypher66c64f62018-04-20 06:46:09 +000026 print('Unbalanced ' + line.rstrip());
vitalybuka0239a5b2017-11-01 20:27:06 +000027 for l in stack:
delcypher66c64f62018-04-20 06:46:09 +000028 print(l.rstrip())
vitalybuka0239a5b2017-11-01 20:27:06 +000029
30def ProcessStack(line, f):
31 stack = []
32 while line and line.startswith(' #'):
33 stack += [line]
34 line = f.readline()
35 return line, stack
36
37def ProcessFree(line, f, allocs):
38 if not line.startswith('FREE['):
39 return f.readline()
40
41 addr = int(line.split()[1], 16)
42 next_line, stack = ProcessStack(f.readline(), f)
43 if addr in allocs:
44 del allocs[addr]
45 else:
46 PrintStack(line, stack)
47 return next_line
48
49def ProcessMalloc(line, f, allocs):
50 if not line.startswith('MALLOC['):
51 return ProcessFree(line, f, allocs)
52
53 addr = int(line.split()[1], 16)
54 assert not addr in allocs
55
56 next_line, stack = ProcessStack(f.readline(), f)
57 allocs[addr] = (line, stack)
58 return next_line
59
60def ProcessRun(line, f):
61 if not line.startswith('MallocFreeTracer: START'):
62 return ProcessMalloc(line, f, {})
63
64 allocs = {}
delcypher66c64f62018-04-20 06:46:09 +000065 print(line.rstrip())
vitalybuka0239a5b2017-11-01 20:27:06 +000066 line = f.readline()
67 while line:
68 if line.startswith('MallocFreeTracer: STOP'):
69 global _skip
70 _skip = _skip - 1
delcypher66c64f62018-04-20 06:46:09 +000071 for _, (l, s) in allocs.items():
vitalybuka0239a5b2017-11-01 20:27:06 +000072 PrintStack(l, s)
delcypher66c64f62018-04-20 06:46:09 +000073 print(line.rstrip())
vitalybuka0239a5b2017-11-01 20:27:06 +000074 return f.readline()
75 line = ProcessMalloc(line, f, allocs)
76 return line
77
78def ProcessFile(f):
79 line = f.readline()
80 while line:
81 line = ProcessRun(line, f);
82
83def main(argv):
84 parser = argparse.ArgumentParser()
85 parser.add_argument('--skip', default=0, help='number of runs to ignore')
86 args = parser.parse_args()
87 global _skip
88 _skip = int(args.skip) + 1
89 ProcessFile(sys.stdin)
90
91if __name__ == '__main__':
92 main(sys.argv)