forked from Imagelibrary/rtems
libdl: Add allocator check script
Use with the trace outout to check for allocation leaks.
This commit is contained in:
96
cpukit/libdl/rtl-alloc-check.py
Normal file
96
cpukit/libdl/rtl-alloc-check.py
Normal file
@@ -0,0 +1,96 @@
|
||||
#
|
||||
# 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)
|
||||
Reference in New Issue
Block a user