Skip to content

Instantly share code, notes, and snippets.

@orip
Created October 6, 2022 21:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save orip/4c7f7b552c629a89f9142c8de3290f3c to your computer and use it in GitHub Desktop.
Save orip/4c7f7b552c629a89f9142c8de3290f3c to your computer and use it in GitHub Desktop.
Diff two runs of nm on similar executables to find large symbol size increases
#! /usr/bin/env python3
"""
Build to compare two outputs of this line on fairly identical executables
nm --print-size --radix=d <executable> | grep ' .* .* ' | cut -d' ' -f 2-10
To just see the top symbols, can run e.g
nm --print-size --size-sort --radix=d <executable>
"""
from collections import Counter
import re
import subprocess
import sys
import textwrap
from typing import NamedTuple
class Diff(NamedTuple):
old_max: int
new_max: int
section: str
@property
def size(self):
return self.new_max - self.old_max
def get_diffs():
diff = subprocess.run(
["diff", "-u0"] + sys.argv[1:], capture_output=True
).stdout.decode("utf-8")
# strip filenames
diff = diff[diff.index("@") :]
diff_sections = re.split(r"^@@.*@@$", diff, flags=re.MULTILINE)
def sizes_histogram(section, prefix):
return Counter(
int(line.split()[0].strip("-+"))
for line in section.splitlines()
if line.startswith(prefix)
)
for section in diff_sections:
section = section.strip()
pluses = sizes_histogram(section, prefix="+")
minuses = sizes_histogram(section, prefix="-")
if pluses == minuses:
# no change
continue
if not pluses or not minuses:
# not a diff
continue
# some sizes changed
yield Diff(section=section, old_max=max(minuses), new_max=max(pluses))
def main():
MB = 1048576
big_diffs = sorted(
(x for x in get_diffs() if x.size > MB), key=lambda x: x.size, reverse=True
)
for diff in big_diffs[:20]:
print(
f"""
=====
{diff.size/1048576:.1f} MB increase | {100*diff.new_max/diff.old_max - 100:.1f}% | {diff.old_max} => {diff.new_max}
-----
{diff.section}
""".strip()
)
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment