vitalybuka | 0239a5b | 2017-11-01 20:27:06 +0000 | [diff] [blame] | 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 | |
| 18 | import argparse |
| 19 | import sys |
| 20 | |
| 21 | _skip = 0 |
| 22 | |
| 23 | def PrintStack(line, stack): |
| 24 | global _skip |
| 25 | if _skip > 0: |
| 26 | return |
delcypher | 66c64f6 | 2018-04-20 06:46:09 +0000 | [diff] [blame^] | 27 | print('Unbalanced ' + line.rstrip()); |
vitalybuka | 0239a5b | 2017-11-01 20:27:06 +0000 | [diff] [blame] | 28 | for l in stack: |
delcypher | 66c64f6 | 2018-04-20 06:46:09 +0000 | [diff] [blame^] | 29 | print(l.rstrip()) |
vitalybuka | 0239a5b | 2017-11-01 20:27:06 +0000 | [diff] [blame] | 30 | |
| 31 | def ProcessStack(line, f): |
| 32 | stack = [] |
| 33 | while line and line.startswith(' #'): |
| 34 | stack += [line] |
| 35 | line = f.readline() |
| 36 | return line, stack |
| 37 | |
| 38 | def 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 | |
| 50 | def 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 | |
| 61 | def ProcessRun(line, f): |
| 62 | if not line.startswith('MallocFreeTracer: START'): |
| 63 | return ProcessMalloc(line, f, {}) |
| 64 | |
| 65 | allocs = {} |
delcypher | 66c64f6 | 2018-04-20 06:46:09 +0000 | [diff] [blame^] | 66 | print(line.rstrip()) |
vitalybuka | 0239a5b | 2017-11-01 20:27:06 +0000 | [diff] [blame] | 67 | line = f.readline() |
| 68 | while line: |
| 69 | if line.startswith('MallocFreeTracer: STOP'): |
| 70 | global _skip |
| 71 | _skip = _skip - 1 |
delcypher | 66c64f6 | 2018-04-20 06:46:09 +0000 | [diff] [blame^] | 72 | for _, (l, s) in allocs.items(): |
vitalybuka | 0239a5b | 2017-11-01 20:27:06 +0000 | [diff] [blame] | 73 | PrintStack(l, s) |
delcypher | 66c64f6 | 2018-04-20 06:46:09 +0000 | [diff] [blame^] | 74 | print(line.rstrip()) |
vitalybuka | 0239a5b | 2017-11-01 20:27:06 +0000 | [diff] [blame] | 75 | return f.readline() |
| 76 | line = ProcessMalloc(line, f, allocs) |
| 77 | return line |
| 78 | |
| 79 | def ProcessFile(f): |
| 80 | line = f.readline() |
| 81 | while line: |
| 82 | line = ProcessRun(line, f); |
| 83 | |
| 84 | def 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 | |
| 92 | if __name__ == '__main__': |
| 93 | main(sys.argv) |