[PATCH 3/6] libdl: Add allocator check script

chrisj at rtems.org chrisj at rtems.org
Wed May 6 08:41:34 UTC 2020


From: Chris Johns <chrisj at rtems.org>

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 <chrisj at 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)
-- 
2.24.1



More information about the devel mailing list