Whamcloud - gitweb
Branch b1_4
authoradilger <adilger>
Wed, 31 May 2006 19:37:15 +0000 (19:37 +0000)
committeradilger <adilger>
Wed, 31 May 2006 19:37:15 +0000 (19:37 +0000)
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
build/checkstack.pl [new file with mode: 0644]

index d9e18a8..0981340 100644 (file)
@@ -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 (file)
index 0000000..3504e96
--- /dev/null
@@ -0,0 +1,83 @@
+#!/usr/bin/perl
+#      Check the stack usage of functions
+#
+#      Copyright Joern Engel <joern@wh.fh-wedel.de>
+#      Inspired by Linus Torvalds
+#      Original idea maybe from Keith Owens
+#      s390 port and big speedup by Arnd Bergmann <arnd@bergmann-dalldorf.de>
+#      Modified to have simpler output format by Dan Kegel
+#
+#      Usage:
+#      objdump -d vmlinux | stackcheck.pl [arch]
+#
+#      find <moduledir> -name "*.o" | while read M; do
+#              objdump -d $M | perl ~/checkstack.pl <arch> | \
+#                      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 = <STDIN>) {
+       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";
+}