David Creelman | 13 May 2012 10:58
Picon
Gravatar

Drawing a call graph of a block of lisp code (general lisp question)

Hi,
I have a bunch of lisp code that I want to draw the call graph of (I'm
thinking of generating something with graphviz).

Has someone written something that will look for all of the function
calls in a defun? I imagine a recursive function called from a macro
could do this. I've had a go at writing it with loop, but I'm not sure
how to get it to recurse over subtrees of calls. Small confession, I'm
not real good at recursive functions. The recursive function I wrote
seemed to always end up working like flatten.

It would be nice to be able to do something like

(callgraph graph1
(defun caller (a b)
  (fun1 a)
  (fun2 b))

(defun fun1 (a)
  (print a))

(defun fun2 (a)
  (print a)))

Which would generate
digraph graph1 {
  caller -> fun1
  caller -> fun2 }

... I'm away from graphviz doco as I write this, so I may have got the
(Continue reading)

Ph. Marek | 13 May 2012 11:14
Picon

Re: Drawing a call graph of a block of lisp code (general lisp question)

Hello David,

> I have a bunch of lisp code that I want to draw the call graph of (I'm
> thinking of generating something with graphviz).
...
> Does anyone know of any modules that would do this for me?
Slime/swank have cross-reference queries, so I wouldn't be surprised if they'd 
give you a complete call-graph, too.

If they don't (yet), it would be easy to do from the callers-of and callees 
information.

Please keep me/us updated ... I'd be interested in that as well.

Regards,

Phil

------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
Nikodemus Siivola | 13 May 2012 11:38
Gravatar

Re: Drawing a call graph of a block of lisp code (general lisp question)

See:

 sb-introspect:who-calls
 sb-introspect:find-function-callees

The first should be accurate and include inlined call sites. The
latter only knows about full calls. You can also build SBCL with
--fancy to get XREF data for internals as well.

Cheers,

 -- nikodemus

------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
David Creelman | 17 May 2012 08:53
Picon
Gravatar

Re: Drawing a call graph of a block of lisp code (general lisp question)

On Sun, May 13, 2012 at 12:38:44PM +0300, Nikodemus Siivola wrote:
> See:
> 
>  sb-introspect:who-calls
>  sb-introspect:find-function-callees
> 
> The first should be accurate and include inlined call sites. The
> latter only knows about full calls. You can also build SBCL with
> --fancy to get XREF data for internals as well.

Hi Nikodemus,
Thanks for that. That did the trick. It looks like Debian has built
with --fancy as there is a lot of stuff that comes back from who-calls.

I threw together some code that lets me build a call graph, I'm including the
guts of it here in case someone else would like to use it or improve it.

This will produce a graphviz style call directed graph.

For small bits of code, it may be useful. (My code has got quite
large, making a very dense, large graph, so I may need to rethink how to 
do this). Nonetheless, being able to see where stuff is called is
very useful to me, so thanks. 

(defun clean-symbol (sym)
  (substitute #\2 #\> (remove #\- (format nil "~A" sym))))

(let ((lst ())
      (fn-hash (make-hash-table))
      (package-name "MY-PACKAGE-NAME"))
(Continue reading)


Gmane