ccusage: A Powerful Tool for Analyzing C/C++ Source Code Call Hotspots and Identifying Performance Bottlenecks!

Today, I want to share a small tool I recently discovered — <span>ccusage</span>. Although the project is small, its functionality is indeed impressive! I tried it out, and it **directly analyzed tens of thousands of lines of C code in a project, producing results in seconds, and the performance skyrocketed!** It is fantastic for investigating code complexity, function coupling, and even hot path call graphs.

This tool is perfect for C projects that often have tens of thousands of lines, a bunch of macros, nested structures, and header file dependency hell.

ccusage: A Powerful Tool for Analyzing C/C++ Source Code Call Hotspots and Identifying Performance Bottlenecks!

Now, let’s take a look at how I got started with this tool and discuss some of its design concepts.

1) Project Overview: What is ccusage?

In one sentence: This is a source-level static analysis tool used to count the “usage frequency” and “occurrence location” of various C/C++ language elements in a project.

Specifically, it supports:

  • Counting the number of times functions are called and who calls them;
  • Analyzing the usage locations of macro definitions (define);
  • Frequency of structure member appearances;
  • Optionally generating DOT format call graphs (graphviz).

It’s somewhat like a lightweight version of clang-analyzer or cscope, but easier to use without complicated compilation parameters.

Moreover, it is based on <span>libclang</span>, so its accuracy is much higher than your own regex matching, avoiding a lot of false positives.

ccusage: A Powerful Tool for Analyzing C/C++ Source Code Call Hotspots and Identifying Performance Bottlenecks!

2) Installation & Dependencies

I used macOS on an M1 chip, and to install this, you need the following dependencies:

  • Python 3.10+
  • <span>libclang</span> (install on mac using <span>brew install llvm</span>)
  • <span>graphviz</span> (optional: used for visualizing call graphs)

Installation steps are as follows:

git clone https://github.com/ryoppippi/ccusage.git
cd ccusage
pip install -r requirements.txt

Note! The path for <span>libclang</span> that this tool depends on may need to be configured manually. I set it up like this on my M1:

export LIBCLANG_PATH="/opt/homebrew/opt/llvm/lib"

Then you can run it.

ccusage: A Powerful Tool for Analyzing C/C++ Source Code Call Hotspots and Identifying Performance Bottlenecks!

3) How to Use? I Analyzed an Old Project with It!

I found an old embedded project in our company, written purely in C, with over 30,000 lines. I wanted to see which function is the “most critical call point”.

Direct command:

python ccusage.py -r ./your_project_path -t function -o out/function_usage.json

The resulting JSON file looks something like this:

{
  "funcA": {
    "count": 12,
    "locations": [...],
    "called_by": [...],
    "calls": [...]
  },
  ...
}

I immediately noticed several functions were called hundreds of times, and the code quality was concerning! There was a function called “util_parse_cmd” that was called by the UI layer, the hardware layer, and the network protocol all at once…It was a complete coupling monster!

ccusage: A Powerful Tool for Analyzing C/C++ Source Code Call Hotspots and Identifying Performance Bottlenecks!

Doesn’t it feel a bit like a Flamegraph? However, this is more low-level, allowing you to see the call relationships at the code level directly.

4) It Can Also Generate Graphs! Call Graphs Are Very Intuitive!

Next, I used its graphical feature to export a DOT graph file:

python ccusage.py -r ./your_project_path -t function -g out/callgraph.dot

Then use <span>dot</span> to convert it to PNG:

dot -Tpng out/callgraph.dot -o callgraph.png

I put it in a PPT to show my leader, and we found that a function in one of our modules actually played the role of the “core spider web”, with dozens of edges radiating from it!

He remarked, “No wonder this module explodes every time we modify it”…

5) Summary of Use Cases: Who Is This Tool Suitable For?

I believe the following types of people are very suitable for using this tool:

1) People Taking Over Old Projects — Want to quickly understand the code structure without relying on visual inspection of the source code; 2) Performance Analysts — Looking for hotspot functions to prioritize optimization; 3) Pre-refactoring Analysis — Identifying functions that are “overused” as candidates for splitting; 4) Teaching/Reading Source Code — Analyzing the function structure of open-source projects to aid learning; 5) Documentation Generation — Including call graphs in project documentation, perfect.

6) A Few Pitfalls to Share

During my use, I discovered a few small pitfalls, and I’d like to share them:

  • Some projects require importing compilation information using <span>compile_commands.json</span>, otherwise it will report missing header files;
  • If the structures are written very messily, it is recommended to first export analysis using <span>-t struct</span> separately;
  • Some header files have nested macros that can lead to inaccurate recognition by libclang, so use with caution;
  • Currently, it does not support template analysis, so projects heavily using C++ templates are not very suitable;

However, the overall accuracy and analysis speed are indeed impressive, much stronger than writing your own scripts and regex!

If you are interested, you can give it a try. If you have ever taken over a messy project with tens of thousands of lines, this tool might just save you!

See you in the next article!

The project is open-source here:github.com/ryoppippi/ccusage

-END

I have created a free RPA tutorial for everyone: songshuhezi.com/rpa.html

Finally, I want to share some good side job resources. Click the public account below and reply with the keyword: Side Job to receive it. You can also connect with me to get it via WeChat:hls404

Leave a Comment