Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:16

0001 # SPDX-License-Identifier: BSD-2-Clause
0002 
0003 #
0004 # Check the allocations for libdl:
0005 #
0006 #  1. Turn on the allocation trace.
0007 #
0008 #  2. Load and unload object files.
0009 #
0010 #  3. Capture the trace output and feed to this tool
0011 
0012 # Copyright (c) 2019 Chris Johns <chrisj@rtems.org>.
0013 # All rights reserved.
0014 #
0015 # Redistribution and use in source and binary forms, with or without
0016 # modification, are permitted provided that the following conditions
0017 # are met:
0018 # 1. Redistributions of source code must retain the above copyright
0019 #    notice, this list of conditions and the following disclaimer.
0020 # 2. Redistributions in binary form must reproduce the above copyright
0021 #    notice, this list of conditions and the following disclaimer in the
0022 #    documentation and/or other materials provided with the distribution.
0023 #
0024 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0025 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0026 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0027 # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0028 # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0029 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0030 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0031 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0032 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0033 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0034 # POSSIBILITY OF SUCH DAMAGE.
0035 
0036 from __future__ import print_function
0037 
0038 import argparse
0039 
0040 
0041 class libdl_trace(object):
0042     def __init__(self, name):
0043         self.name = name
0044         self.trace = {'alloc': []}
0045 
0046     def load(self):
0047         with open(self.name, 'r') as f:
0048             lc = 0
0049             for line in f:
0050                 line = line[:-1]
0051                 lc += 1
0052                 if line.startswith('rtl: '):
0053                     if line.startswith('rtl: alloc: '):
0054                         self.trace['alloc'] += [(lc, line)]
0055 
0056     def check_allocs(self):
0057         allocs = {}
0058         locks = 0
0059         wr_enable = False
0060         for lc, line in self.trace['alloc']:
0061             ls = line.split(' ')
0062             if len(ls) > 3:
0063                 if ls[2] == 'new:':
0064                     addr = ls[4].split('=')[1]
0065                     size = ls[5].split('=')[1]
0066                     count = 0
0067                     if addr in allocs:
0068                         alc, alloced, asize, count = allocs[addr]
0069                         if alloced:
0070                             print(
0071                                 '%5d: already alloced: %5d: addr=%-9s size=%-9s count=%d'
0072                                 % (lc, alc, addr, asize, count))
0073                     allocs[addr] = (lc, True, size, count + 1)
0074                 elif ls[2] == 'del:':
0075                     addr = ls[4].split('=')[1]
0076                     if addr != '0':
0077                         if addr not in allocs:
0078                             print('%5d: delete never alloced: addr=%s' %
0079                                   (lc, addr))
0080                         else:
0081                             alc, alloced, size, count = allocs[addr]
0082                             if not alloced:
0083                                 print(
0084                                     '%5d: delete not alloced: %5d: addr=%-9s size=%-9s count=%d'
0085                                     % (lc, alc, addr, size, count))
0086                         allocs[addr] = (lc, False, size, count)
0087         alloced_remaiing = 0
0088         addresses = sorted(list(allocs.keys()))
0089         for addr in addresses:
0090             lc, alloced, size, count = allocs[addr]
0091             if alloced:
0092                 print('%5d: never deleted: addr=%-9s size=%-9s count=%d' %
0093                       (lc, addr, size, count))
0094                 alloced_remaiing += int(size)
0095         if alloced_remaiing != 0:
0096             print("Amount alloced: %d" % (alloced_remaiing))
0097 
0098 
0099 def run(args):
0100     argsp = argparse.ArgumentParser(prog='rtl-alloc-check',
0101                                     description='Audit libdl allocations')
0102     argsp.add_argument('traces', help='libdl trace files', nargs='+')
0103 
0104     opts = argsp.parse_args(args[1:])
0105 
0106     for t in opts.traces:
0107         trace = libdl_trace(t)
0108         trace.load()
0109         trace.check_allocs()
0110 
0111 
0112 if __name__ == "__main__":
0113     import sys
0114     run(sys.argv)