mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Carl Spalletta <cspalletta@yahoo.com>
To: linux-kernel@vger.kernel.org
Subject: 'fscope': a new debugging tool
Date: Mon, 26 May 2003 12:50:22 -0700 (PDT)	[thread overview]
Message-ID: <20030526195022.56736.qmail@web41501.mail.yahoo.com> (raw)

#!/usr/local/bin/perl -s
# (c) 2003 Carl Spalletta under GPL-v2 cspalletta@yahoo.com

# PURPOSE:
# Traces chains of function calls as far back as possible - i.e.,
# to a callback, syscall or interrupt handler. Also, with the
# '-cycles' option set, warns of possible cycles in kernel code.

# USAGE:
# For example we want to find all the ways there are to reach function
# do_mmap_pgoff() within the kernel.  Whereas 'cscope' would only give
# us it's immediate callers, we recreate the whole reverse call tree with
# the command 'fscope -func=do_mmap_pgoff'. It produces about 20 lines of
# output, each line a unique path to do_mmap_pgoff. The command
# 'fscope -func=add_to_swap_cache' produces over 5000 paths. Arranged
# into tabular form with 'column -t' they form some revealing patterns.

# INSTALLATION
# First, install 'cscope' (available from sourceforge or as an rpm).
# Then before running 'fscope' for the first time, give the command
# "cscope -Rkq" in your source directory to setup the indices.
#
# Then you may use this program at will, after verifying 2 things:
#
#    1) That variable $cmd points to some shell script (here called
#      'fscope.cmd'), which is set executable, and whose contents are:
#
#          "cscope -d -L -3$1 | perl -lane 'print $F[1]' | sort -u"
#
#    2) That the hashbang line of _this_ file refers to your local perl.

# OPTIONAL, BUT RECOMMENDED:
#  For cleaner output _before_ running 'cscope -Rkq' - which only need
# be done once for any source tree - you may clone your source dir with
#
#   cpio -pdumv --link
#
# Then prune away the foreign architecture directories & header files,
# as well as any drivers, filesystems, etc, not part of your setup.

# LIMITATIONS:
# Obviously this is not perfect - it may give false positives. Consider
# a call chain '..A..B..C..' where 'B' indirectly calls function 'C' to
# access a resource protected by some non-blocking synchronization
# primitive which happens, for this chain, to always be held by 'A'.
# Thus, function 'C' will never enter it's critical section from this
# particular call chain (nor will it deadlock), and any functions con-
# tained in it's critical section can never be reached from this chain.
# 
# Nonetheless 'fscope' considers that it _is_ possible, since it assumes
# that any call within a function is ultimately reachable from any chain
# the function belongs to.
#
# In other words it's analysis is structural, not logical.

# NB: the interesting part of the code is in the loop after label 'NB:'


BEGIN
{
sub leveln;
$usage="usage: $0 -func=<funcname> [-cycles] [-debug]";
if(!(defined $func))
  {
  print "$usage\n";
  exit;
  }
}

#cycles lead to infinite expansion
sub cycle
{
  my $arrayref  = shift(@_);
  my $candidate = shift(@_);
  my $arrayelem;

  #this argument was supposed to have been
  #cleaned up _before_ the call. However..
  $candidate =~ s/^\W*(\w+)\W*$/\1/;

  foreach $arrayelem (@$arrayref)
  {
    $arrayelem =~ s/^\W*(\w+)\W*$/\1/;
    if($arrayelem eq $candidate)
    {
      if($cycles)
      {
CYCLE0:
        print "cycle detected: ";
	print join ':',@$arrayref;
	print ":$arrayelem\n";
      }
      return 1;
    }
  }
  return 0;
} #end sub cycle

#recurse until we can go no further
sub leveln
{
  my $i,$xfunc,$cmd;
  local @cmd0;

  $xfunc=pop @_;
  push @_,$xfunc;

  #eliminate the line noise :(
  $xfunc =~ s/^\W*(\w+)\W*$/\1/;

  #insert your command here, but preserve
  #the embedded space after the path name
  $cmd = "/usr/local/bin/fscope.cmd " . $xfunc;
  @cmd0= qx/$cmd/;

  if($debug)
  {
DEBUG1:
    print "\n";
    print 'leveln[';
    print join ';',@_;
    print ']';
    print "\n:";
    print join ':',@cmd0;
  }

  #at this point @cmd0 includes all callers of $xfunc.
  if(@cmd0)
  {
    my @args=@_;
NB:
    #this loop contains the really interesting bits..
    foreach $i (@cmd0)
    {
      $i =~ s/^\W*(\w+)\W*$/\1/;
      next if $i eq $xfunc;

      #invalid value - a cycle
      if(cycle(\@args,$i))
      {
        return;
      }
      #numeric value - not called directly by anything
      #thus end of call chain
      elsif($i=~m/^\d+$/)
      {
        return;
      }
      ##elsif($i=~m/^sys_\w+$/) { return; } #exclude linux syscalls
      #default action
      #  go one level deeper
      else
      {
        push @args,$i;
        leveln @args;
        pop @args;
      }
    } #end foreach $i
  return;
  } #end if @cmd0
  else
  {
    if($debug)
    {
DEBUG2:
      print "\@_ at terminal node <<@_>>\n";
      return;
    } #end if debug
    else
    {
      #Hoorah!
      #This is where we output the call chain
      print "@_\n";
      return;
    } #end if not debug
  } #end not @cmd0
} #end sub leveln

leveln $func;



             reply	other threads:[~2003-05-26 19:37 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-05-26 19:50 Carl Spalletta [this message]
2003-05-26 22:27 Carl Spalletta
2003-05-26 23:09 Carl Spalletta
2003-05-28 21:33 ` Pavel Machek

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20030526195022.56736.qmail@web41501.mail.yahoo.com \
    --to=cspalletta@yahoo.com \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®