summaryrefslogblamecommitdiffstats
path: root/cpukit/libdl/rtl-alloc-check.py
blob: c2145a768e266ba3736a9e645c495b5aeb53bcb7 (plain) (tree)































































































                                                                                                
#
# Copyright (c) 2019 Chris Johns <chrisj@rtems.org>.
# 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)