Files
lmxopcua/scripts/validation/opcua-lifecycle-memory/summarize.py
T

46 lines
1.7 KiB
Python

#!/usr/bin/env python3
"""Emit mapping-category totals without path names from local Linux /proc/PID/smaps."""
import argparse
from collections import defaultdict
import json
from pathlib import Path
import re
HEADER = re.compile(r"^[0-9a-f]+-[0-9a-f]+\s+(\S+)\s+\S+\s+\S+\s+\S+\s*(.*)$")
METRIC = re.compile(r"^(Size|Rss|Pss|Private_Dirty|Private_Clean|Anonymous):\s+(\d+) kB$")
def summarize(path):
groups = defaultdict(lambda: defaultdict(int))
group = None
for line in path.read_text().splitlines():
header = HEADER.match(line)
if header:
permissions, name = header.groups()
if "doublemapper" in name:
group = "jit-doublemapper"
elif name == "[heap]":
group = "native-heap"
elif name.startswith("[stack"):
group = "stack"
elif not name:
group = "anonymous-exec" if "x" in permissions else "anonymous-write" if "w" in permissions else "anonymous-read"
elif name.endswith(".dll"):
group = "managed-assembly-files"
elif ".so" in name:
group = "native-library-files"
elif name.startswith("["):
group = "other-kernel-mappings"
else:
group = "other-files"
elif group and (metric := METRIC.match(line)):
groups[group][metric[1]] += int(metric[2]) * 1024
return dict(groups)
if __name__ == "__main__":
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("files", nargs="+", type=Path)
args = parser.parse_args()
print(json.dumps([{"sample": index, "groups": summarize(path)} for index, path in enumerate(args.files)], indent=2))