Whamcloud - gitweb
LU-10657 utils: fd leak in mirror_split()
[fs/lustre-release.git] / lustre / tests / checkstack.pl
1 #!/usr/bin/perl
2 #       Check the stack usage of functions
3 #
4 #       Copyright Joern Engel <joern@wh.fh-wedel.de>
5 #       Inspired by Linus Torvalds
6 #       Original idea maybe from Keith Owens
7 #       s390 port and big speedup by Arnd Bergmann <arnd@bergmann-dalldorf.de>
8 #       Modified to have simpler output format by Dan Kegel
9 #
10 #       Usage:
11 #       objdump -d vmlinux | stackcheck.pl [arch]
12 #
13 #       find <moduledir> -name "*.o" | while read M; do
14 #               objdump -d $M | perl ~/checkstack.pl <arch> | \
15 #                       sed "s/^/`basename $M`: /" ; done | \
16 #       awk '/esp/ { print $5, $2, $4 }' | sort -nr
17
18 #       TODO :  Port to all architectures (one regex per arch)
19
20 # check for arch
21
22 # $re is used for three matches:
23 # $& (whole re) matches the complete objdump line with the stack growth
24 # $1 (first bracket) matches the code that will be displayed in the output
25 # $2 (second bracket) matches the size of the stack growth
26 #
27 # use anything else and feel the pain ;)
28 {
29         my $arch = shift;
30         $x      = "[0-9a-f]{1,5}";              # hex number
31         $d      = "[0-9]{1,5}"; # decimal number
32         if ($arch eq "") {
33                 $arch = `uname -m`;
34         }
35         if ($arch =~ /^i[3456]86$/) {
36                 #c0105234:       81 ec ac 05 00 00       sub    $0x5ac,%esp
37                 $re = qr/^.*(sub    \$(0x$x),\%esp)$/o;
38                 $todec = sub { return hex($_[0]); };
39         } elsif ($arch =~ /^ia64$/) {
40                 #e0000000044011fc:       01 0f fc 8c     adds r12=-384,r12
41                 $re = qr/.*(adds.*r12=-($d),r12)/o;
42                 $todec = sub { return $_[0]; };
43         } elsif ($arch =~ /^mips64$/) {
44                 #8800402c:       67bdfff0        daddiu  sp,sp,-16
45                 $re = qr/.*(daddiu.*sp,sp,-($d))/o;
46                 $todec = sub { return $_[0]; };
47         } elsif ($arch =~ /^mips$/) {
48                 #88003254:       27bdffe0        addiu   sp,sp,-32
49                 $re = qr/.*(addiu.*sp,sp,-($d))/o;
50                 $todec = sub { return $_[0]; };
51         } elsif ($arch =~ /^ppc$/) {
52                 #c00029f4:       94 21 ff 30     stwu    r1,-208(r1)
53                 $re = qr/.*(stwu.*r1,-($x)\(r1\))/o;
54                 $todec = sub { return hex($_[0]); };
55         } elsif ($arch =~ /^s390x?$/) {
56                 #   11160:       a7 fb ff 60             aghi   %r15,-160
57                 $re = qr/.*(ag?hi.*\%r15,-($d))/o;
58                 $todec = sub { return $_[0]; };
59         } else {
60                 print "Usage:  objdump -d vmlinux | checkstack.pl [arch]\n";
61                 print "where arch is i386, ia64, mips, mips64, ppc, or s390\n";
62                 print "Each output line gives a function's stack usage, name\n";
63                 print "Lines are output in order of decreasing stack usage\n";
64                 die("wrong or unknown architecture\n");
65         }
66 }
67
68 $funcre = qr/^[0-9a-f]* \<(.*)\>:$/;
69 while ($line = <STDIN>) {
70         if ($line =~ m/$funcre/) {
71                 ($func = $line) =~ s/$funcre/\1/;
72                 chomp($func);
73         }
74         if ($line =~ m/$re/) {
75                 push(@stack, &$todec($2)." ".$func);
76                 # don't expect more than one stack allocation per function
77                 $func .= " ** bug **";
78         }
79 }
80
81 foreach (sort { $b - $a } (@stack)) {
82         print $_."\n";
83 }