From c3df928cd9f2ff66449954c49ae2ed8a3bcf68d0 Mon Sep 17 00:00:00 2001 From: adilger Date: Wed, 31 May 2006 19:37:15 +0000 Subject: [PATCH] Branch b1_4 Move checkstack target up to top-level autoMakefile so "make checkstack" works more easily. This will print out the top stack users (though not total callchain stack usage). --- autoMakefile.am | 23 +++++++++++++++ build/checkstack.pl | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 106 insertions(+) create mode 100644 build/checkstack.pl diff --git a/autoMakefile.am b/autoMakefile.am index d9e18a8..0981340 100644 --- a/autoMakefile.am +++ b/autoMakefile.am @@ -1 +1,24 @@ include build/autoMakefile.am.toplevel + +CSTK=/tmp/checkstack +CSTKO=/tmp/checkstack.orig + +checkstack: + [ -f ${CSTK} -a ! -s ${CSTKO} ] && mv -f ${CSTK} ${CSTKO} || true + { for i in lustre/* lnet/* ; do \ + MOD=$$i/`basename $$i`; \ + [ -f $$MOD.ko ] && MOD=$$MOD.ko || MOD=$$MOD.o; \ + [ -f $$MOD ] && objdump -d $$MOD | perl build/checkstack.pl; \ + done; \ + for i in lnet/klnds/*; do \ + MOD=$$i/k`basename $$i`; \ + [ -f $$MOD.ko ] && MOD=$$MOD.ko || MOD=$$MOD.o; \ + [ -f $$MOD ] && objdump -d $$MOD | perl build/checkstack.pl; \ + done } | sort -nr > ${CSTK} + [ -f ${CSTKO} ] && ! diff -u ${CSTKO} ${CSTK} || head -30 ${CSTK} + +checkstack-update: + [ -f ${CSTK} ] && mv -f ${CSTK} ${CSTKO} + +checkstack-clean: + rm -f ${CSTK} ${CSTKO} diff --git a/build/checkstack.pl b/build/checkstack.pl new file mode 100644 index 0000000..3504e96 --- /dev/null +++ b/build/checkstack.pl @@ -0,0 +1,83 @@ +#!/usr/bin/perl +# Check the stack usage of functions +# +# Copyright Joern Engel +# Inspired by Linus Torvalds +# Original idea maybe from Keith Owens +# s390 port and big speedup by Arnd Bergmann +# Modified to have simpler output format by Dan Kegel +# +# Usage: +# objdump -d vmlinux | stackcheck.pl [arch] +# +# find -name "*.o" | while read M; do +# objdump -d $M | perl ~/checkstack.pl | \ +# sed "s/^/`basename $M`: /" ; done | \ +# awk '/esp/ { print $5, $2, $4 }' | sort -nr + +# TODO : Port to all architectures (one regex per arch) + +# check for arch +# +# $re is used for three matches: +# $& (whole re) matches the complete objdump line with the stack growth +# $1 (first bracket) matches the code that will be displayed in the output +# $2 (second bracket) matches the size of the stack growth +# +# use anything else and feel the pain ;) +{ + my $arch = shift; + $x = "[0-9a-f]{3,5}"; # hex number >= 256 + $d = "([0-9]{2}|[2-9])[0-9]{2}"; # decimal number >= 200 + if ($arch eq "") { + $arch = `uname -m`; + } + if ($arch =~ /^i[3456]86$/) { + #c0105234: 81 ec ac 05 00 00 sub $0x5ac,%esp + $re = qr/^.*(sub \$(0x$x),\%esp)$/o; + $todec = sub { return hex($_[0]); }; + } elsif ($arch =~ /^ia64$/) { + #e0000000044011fc: 01 0f fc 8c adds r12=-384,r12 + $re = qr/.*(adds.*r12=-($d),r12)/o; + $todec = sub { return $_[0]; }; + } elsif ($arch =~ /^mips64$/) { + #8800402c: 67bdfff0 daddiu sp,sp,-16 + $re = qr/.*(daddiu.*sp,sp,-($d))/o; + $todec = sub { return $_[0]; }; + } elsif ($arch =~ /^mips$/) { + #88003254: 27bdffe0 addiu sp,sp,-32 + $re = qr/.*(addiu.*sp,sp,-($d))/o; + $todec = sub { return $_[0]; }; + } elsif ($arch =~ /^ppc$/) { + #c00029f4: 94 21 ff 30 stwu r1,-208(r1) + $re = qr/.*(stwu.*r1,-($x)\(r1\))/o; + $todec = sub { return hex($_[0]); }; + } elsif ($arch =~ /^s390x?$/) { + # 11160: a7 fb ff 60 aghi %r15,-160 + $re = qr/.*(ag?hi.*\%r15,-($d))/o; + $todec = sub { return $_[0]; }; + } else { + print "Usage: objdump -d vmlinux | checkstack.pl [arch]\n"; + print "where arch is i386, ia64, mips, mips64, ppc, or s390\n"; + print "Each output line gives a function's stack usage, name\n"; + print "Lines are output in order of decreasing stack usage\n"; + die("wrong or unknown architecture\n"); + } +} + +$funcre = qr/^[0-9a-f]* \<(.*)\>:$/; +while ($line = ) { + if ($line =~ m/$funcre/) { + ($func = $line) =~ s/$funcre/\1/; + chomp($func); + } + if ($line =~ m/$re/) { + push(@stack, &$todec($2)." ".$func); + # don't expect more than one stack allocation per function + $func .= " ** bug **"; + } +} + +foreach (sort { $b - $a } (@stack)) { + print $_."\n"; +} -- 1.8.3.1