xfs
[Top] [All Lists]

Re: Large Stack Usage in One More Function

To: Danny Cox <danscox@xxxxxxxxxxxxxx>
Subject: Re: Large Stack Usage in One More Function
From: Danny Cox <danscox@xxxxxxxxxxxxxx>
Date: 27 Aug 2002 13:28:56 -0400
Cc: Steve Lord <lord@xxxxxxx>, XFS Mailing List <linux-xfs@xxxxxxxxxxx>
In-reply-to: <1030468972.1611.21.camel@wiley>
References: <1030467482.1611.14.camel@wiley> <1030467882.16697.28.camel@xxxxxxxxxxxxxxxxxxxx> <1030468972.1611.21.camel@wiley>
Sender: linux-xfs-bounce@xxxxxxxxxxx
Hmmm.

On Tue, 2002-08-27 at 13:22, Danny Cox wrote:
> -- Binary/unsupported file stripped by Ecartis --
> -- Type: text/x-perl
> -- File: check_stack

        Well, I guess the attachment was stripped.  I'll try to inline it:
======================================================
#!/usr/bin/perl
# check_stack --- check for too deep stack depths; it most likely only
#               only works for the linux kernel....

use 5.006;
use strict;
use warnings;
use Getopt::Std;
use lib "blib/lib";
use Disassemble::X86;

use vars qw ( $opt_d );
getopts ("d") and $#ARGV == 1 or die <<END_USAGE;
usage: $0 [-d] vmlinux System.map
-d  debug ON
END_USAGE

# slurp up the whole object file
open OBJ, "<$ARGV[0]" or die "$0: can't read $ARGV[0]: $!\n";
my $slash_save = $/;
undef $/;
my $file = <OBJ>;
close OBJ;
$/ = $slash_save;

# init the disassembler
my $dis = Disassemble::X86->new (
        start => 0xc0100000 - 0x1000,   # text addr - file offset
        pos   => 0,
        size  => 32,
        text  => $file,
);

# you may change these as you see fit

# max_check is the maximum number of instructions to scan for the 'sub
esp,...'
#       before giving up
my $max_check = 10;

# stack_limit is the size that we'll consider worthy of reporting
my $stack_limit = 512;

# end of changables

# max_stack is the maximum stack size we saw
my $max_stack = 0;

# open System.map.  It contains the address, type, and names of each
function
#               (among other things)
open MAP, "<$ARGV[1]" or die "$0: can't read $ARGV[1]: $!\n";

while (<MAP>) {
        my ($addr, $type, $name) = split (' ', $_);
        next if $name =~ /^\./;         # we don't want names like
'.yadda'
        if ($type =~ /^[Tt]$/) {        # we only want text symbols
                print "looking at $name ($addr)\n" if $opt_d;

                $dis->pos (hex ($addr));
                for (my $i = 0; $i < $max_check && !$dis->at_end; $i++)
{
                        my $op = $dis->disasm ();
                        printf "%04x %s\n", $dis->op_start (), $op if
$opt_d;
                        next if (!defined $op);
                        if ($op =~ /sub esp,(0x[[:xdigit:]]+)/) {
                                my $stack = hex ($1);
                                $max_stack = $stack if $stack >
$max_stack;
                                printf "check $name (stack %d)\n",
$stack
                                    if $stack >= $stack_limit;
                                last;
                        }
                }

        }
}
close MAP;

print "max single stack used is $max_stack\n";

exit 0;

# end check_stack
====================================================================

        Well, some of that wrapped, but I guess that's better than not having
it at all!

-- 
kernel, n.: A part of an operating system that preserves the
medieval traditions of sorcery and black art.

Danny


<Prev in Thread] Current Thread [Next in Thread>