Perl subroutine graphing
From TipperWiki
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
