From e9762d74b864f3f9623431045c6b1a3ad69c34c0 Mon Sep 17 00:00:00 2001 From: Chris Johns Date: Wed, 6 May 2020 09:53:45 +1000 Subject: libdl: Add allocator check script Use with the trace outout to check for allocation leaks. --- cpukit/libdl/rtl-alloc-check.py | 96 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 cpukit/libdl/rtl-alloc-check.py diff --git a/cpukit/libdl/rtl-alloc-check.py b/cpukit/libdl/rtl-alloc-check.py new file mode 100644 index 0000000000..c2145a768e --- /dev/null +++ b/cpukit/libdl/rtl-alloc-check.py @@ -0,0 +1,96 @@ +# +# Copyright (c) 2019 Chris Johns . +# All rights reserved. +# +# The license and distribution terms for this file may be +# found in the file LICENSE in this distribution or at +# http://www.rtems.org/license/LICENSE. +# +# Check the allocations for libdl: +# +# 1. Turn on the allocation trace. +# +# 2. Load and unload object files. +# +# 3. Capture the trace output and feed to this tool +# + +from __future__ import print_function + +import argparse + + +class libdl_trace(object): + def __init__(self, name): + self.name = name + self.trace = {'alloc': []} + + def load(self): + with open(self.name, 'r') as f: + lc = 0 + for line in f: + line = line[:-1] + lc += 1 + if line.startswith('rtl: '): + if line.startswith('rtl: alloc: '): + self.trace['alloc'] += [(lc, line)] + + def check_allocs(self): + allocs = {} + locks = 0 + wr_enable = False + for lc, line in self.trace['alloc']: + ls = line.split(' ') + if len(ls) > 3: + if ls[2] == 'new:': + addr = ls[4].split('=')[1] + size = ls[5].split('=')[1] + count = 0 + if addr in allocs: + alc, alloced, asize, count = allocs[addr] + if alloced: + print( + '%5d: already alloced: %5d: addr=%-9s size=%-9s count=%d' + % (lc, alc, addr, asize, count)) + allocs[addr] = (lc, True, size, count + 1) + elif ls[2] == 'del:': + addr = ls[4].split('=')[1] + if addr != '0': + if addr not in allocs: + print('%5d: delete never alloced: addr=%s' % + (lc, addr)) + else: + alc, alloced, size, count = allocs[addr] + if not alloced: + print( + '%5d: delete not alloced: %5d: addr=%-9s size=%-9s count=%d' + % (lc, alc, addr, size, count)) + allocs[addr] = (lc, False, size, count) + alloced_remaiing = 0 + addresses = sorted(list(allocs.keys())) + for addr in addresses: + lc, alloced, size, count = allocs[addr] + if alloced: + print('%5d: never deleted: addr=%-9s size=%-9s count=%d' % + (lc, addr, size, count)) + alloced_remaiing += int(size) + if alloced_remaiing != 0: + print("Amount alloced: %d" % (alloced_remaiing)) + + +def run(args): + argsp = argparse.ArgumentParser(prog='rtl-alloc-check', + description='Audit libdl allocations') + argsp.add_argument('traces', help='libdl trace files', nargs='+') + + opts = argsp.parse_args(args[1:]) + + for t in opts.traces: + trace = libdl_trace(t) + trace.load() + trace.check_allocs() + + +if __name__ == "__main__": + import sys + run(sys.argv) -- cgit v1.2.3