Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I produce a graphical code profile report for C++ code compiled with Clang LLVM?

How do I produce a graphical code profile report for C++ code compiled with Clang LLVM?

  • What command-line options to I pass to clang++ to instruct it to gather profiling data when the code is executed?

  • Into which file(s) is the gathered profiling data stored?

  • What are the post-processing steps to convert the collected profile data into a graphical report that shows how often each function is called, what percentage of time is spent in each function, and from which functions each function is called (similar to https://s3-us-west-2.amazonaws.com/brunorijsman-public/example-rift-python-code-profile.png)?

I have full control over the C++ source code and Makefile.

It has to be LLVM clang++ (GNU g++ is not an option for me). Xcode is also not an option for me.

like image 680
Bruno Rijsman Avatar asked Jan 24 '26 15:01

Bruno Rijsman


1 Answers

Clang supports a couple of different code coverage implementations (which also output how often a line has been executed) such as Source-Based Code Coverage and a gcov-compatible one. Open source tools seems to have better support for gcov output in general, so I would recommend that route.

What command-line options to I pass to clang++ to instruct it to gather profiling data when the code is executed?

  • For Source-Based Code Coverage: According to llvm-cov, the correct flags for gathering profiling data when is -fprofile-instr-generate -fcoverage-mapping when compiling and -fprofile-instr-generate when linking.
  • For the gcov compatible output: -fprofile-arcs -ftest-coverage

Into which file(s) is the gathered profiling data stored?

  • For Source-Based Code Coverage: After you run the program compile and linked with the flags above, the coverage data is stored in default.profraw in your current working directory. The profiling data file name can be changed by recompiling with -fprofile-instr-generate=filename or by setting the environment variable LLVM_PROFILE_FILE before running the executable.
  • For gcov compatible output: After you run the program you will get *.gcda and *.gcno files.

What are the post-processing steps to convert the collected profile data into a graphical report that shows how often each function is called, what percentage of time is spent in each function

  • For Source-Based Code Coverage:

    1. Index your .profraw file into a .profdata file: llvm-profdata merge -o default.profdata -sparse=true default.profraw
    2. Either use llvm-cov show --instr-profile default.profdata ./your_program to view the coverage in the terminal or use llvm-cov export ./your_program --instr-profile default.profdata > out.json to convert your profiling data to JSON and find/create a program to generate a report for you.
  • For gcov-compatible output:

    1. Use lcov or gcovr to generate HTML output. This lets you easily view line and branch coverage for each file. I tend to use gcovr since it is a simple pip install gcovr away if you don't have it installed. Then the usage would be gcovr --gcov-executable "llvm-cov gcov" -r . --html --html-details -o out.html.

and from which functions each function is called (similar to https://s3-us-west-2.amazonaws.com/brunorijsman-public/example-rift-python-code-profile.png)?

For this type of information I would try to have a look at Callgrind and KCacheGrind. I have not found any tool which can generate this type of information given *.profdata or *.gcda files.

like image 193
Joskar Avatar answered Jan 26 '26 07:01

Joskar



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!