Implementing a call graph generator as a cargo extension

I'm looking into writing a call graph generator for Rust as a cargo extension.

A couple of tools exist for this, but they consume huge amounts of memory, or are just incompatible with later versions of Rust. (a few of the ones I found are Rupta, Crabviz, and cargo-call-stack).

My goal is to make a fairly lightweight call graph generator that is able to sacrifice call graph coverage for performance. For instance, I'm ok with it missing calls from function references, dynamic dispatch, or non-concrete generic types.
I want to be able to make cargo do most of the work of resolving dependencies and collecting all the source files for the input crate. And I'd like to have the option to include external dependencies in the generated call graph (though that might go against the light-weight goal).

I'm thinking of trying to extend the compiler like what is shown in this example. However, the answer to this post indicates that extending the compiler is not recommended.

syn is probably the best option for doing this, but I'll need to figure a way to get all the files from a crate (will look into the APIs that cargo provides later).

Thoughts on the best way to go about this?

1 Like

You might be interested in GitHub - rust-lang/project-stable-mir: Define compiler intermediate representation usable by external tools -- that's made to give proof tools access to all the functions, so you could probably use it to see all the TerminatorKind::Calls and ignore the rest of the function bodies.

1 Like