Perl subroutine graphing

From TipperWiki

Jump to: navigation, search

http://headrattle.blogspot.com/2008/02/only-perl-can-parse-perl.html

Eric Maki

---- original message : 2008-02-19 3:57pm : Jay Hannah ----
> I love your article.  :)
>
> Do you know anyone who's done anything similar, graphing Perl subroutine
> calls from Perl 5 source code?   That would be slick...
>
> http://headrattle.blogspot.com/2008/02/only-perl-can-parse-perl.html
>
> Thanks,
>
> j

From: Eric Maki [mailto:eric(at)uc(dot)org]
Sent: Tue 2/19/2008 4:20 PM
To: Jay Hannah
Subject: Re: The Perl Review: Mapping Op Trees

Glad you enjoyed, it was just a fun exercise to understand how
Perl opcode is structured.  I refined it enough to be able to
graph different code structures, which I used to do a talk for a
local PM group.  That's about where I ran out of time for it.

Are you looking specifically to graph the general question: "In
this code, which subs call into which?" or the same question
during actual execution?  In other words, static analysis of the
code, or dynamic analysis of the code as it runs?

They turn out to be fairly different problems.  If you are
looking for the dynamic analysis, then the Perl profiler can help
you out there (see Devel::DProf).  The static analysis is much
trickier.

It's much trickier because Perl permits a number of different
types of dynamic dispatch.  The most common, of course, being
method calls... we can't figure them out until we know what type
of object we have, which we don't know until runtime.  Then there
are code references.  And a bunch of other oddities.

I thought about handling the most basic case in my graphing code
- when we call a statically named sub, we can determine that
relation... at least within a reasonable margin.  Subs are stored
in symbol tables, and those are dynamic, but there are
(relatively) few cases where people mess with those at runtime.

The cases of code references and method calls, though, are
essentially hopeless.  A sub that takes a code ref as an argument
and then calls that has no idea at all what code it might call
until runtime.

Eric

Alan

On Tue, 19 Feb 2008, Jay Hannah wrote:
> Hi Alan --
>
> Any further luck with this since 2000?
>
>    http://www.perlmonks.org/?node_id=25807
>
> It'd sure be neat to kick out some GraphViz on a ball of Perl I just got
> thrown into...
>
> Thanks,
>
> j


From: alan(at)ferrency(dot)com
Sent: Tue 2/19/2008 4:03 PM
To: Jay Hannah
Subject: Re: sub_graph.pl

> Any further luck with this since 2000?
>
>    http://www.perlmonks.org/?node_id=25807

Wow, I wrote that?
That looks pretty cool, I'll have to try it out :)

No, I haven't really worked with that code since I posted it. I changed
jobs a few months after that was published.

However, in the mean time I have hacked up some dot graphs of code since
then, but I didn't do it the way that script does it.

The main flaws with this sort of analysis are that it doesn't handle
things like method calls (inheritence) and code references very well.
I'm not sure I really have much code it would work well on anymore.

What happens when you just throw that script at your perl code? Does it
break, or do something not-so-useful?

Thanks,
Alan


From: alan(at)ferrency(dot)com
Sent: Tue 2/19/2008 4:12 PM
To: Jay Hannah
Subject: Re: sub_graph.pl

Here's an alternate tactic I might use these days:

Run the perl code in the Perl profiler, and use graphviz to visualize
the actual call graph in running code, instead of trying to analyze the
code statically.

This will also potentially let you include performance/profiling
information with each node, such as color coding "hot spots" in the
code.

For inspiration, google "dprofpp graphviz". There's an example in the
GraphViz perl module, and some articles on perl.com that show some other
ways to draw call graphs.

Sorry I don't have a good canned solution handy, but keep me posted if
you find something that works well for you :)

Alan


From: alan(at)ferrency(dot)com
Sent: Tue 2/19/2008 4:43 PM
To: Jay Hannah
Subject: Re: sub_graph.pl

I saw that example on perl.com and it looked like a good way to get you
a call graph.

If you just do profiling and run dprofpp, it will output a textual call
graph for you, with some additional information such as how many times
each function is called, how much time is spent in each function, and
both the callers and called functions within that function.

That seems like more info than the perl.com tree gets you, but you'd
need to do more work to make it into a dotfile.

The main limitation of profiling-based analysis is that you won't see
code paths that aren't exercised in an actual code run. For example,
you'll likely miss a lot of error checking code, or may need to perform
multiple runs with different parameters to make sure you traverse all
possible paths.

It may also be a challenge to do this within a web application, but it's
likely still possible.


I've also done some "web site map" visualization by analyzing apache
logs and applying graphviz to the results.

Alan
Personal tools