Home / Alt manpages / llvm-locstats-18(1)

  • llvm-locstats-18(1)
  • User command
  • linux

Measure DWARF Variable Coverage with llvm-locstats-18

You will finish with a repeatable way to measure whether local variables and parameters have usable DWARF location information across their live scopes. The command prints coverage buckets, overall availability and program-counter coverage, and can compare two instrumented files.

Allow about fifteen minutes. You need the LLVM 18 tool, an executable or object file containing DWARF debug information, and a shell. The examples are read-only: llvm-locstats-18 analyses its input and does not rewrite it. Plotting examples additionally require Python's matplotlib.

Checkpoint

The result you are looking for is a report headed Debug Location Statistics, not a disassembly or a list of source lines.

1. Confirm the tool and input

Start by checking the executable that will actually run. This is an ordinary command and does not need elevated privileges:

$ command -v llvm-locstats-18
/usr/bin/llvm-locstats-18
$ dpkg-query -W -f='${Package} ${Version}\n' llvm-18
llvm-18 1:18.1.3-1ubuntu1

The version shown above is the installed package version on the system used for this guide. Package layouts vary. If command -v prints nothing, stop there and install or expose the matching LLVM tool before investigating your file. Do not substitute an unversioned llvm-locstats without checking which LLVM release it belongs to.

Next, identify a real input. Use an explicit path so you do not accidentally analyse a stale build:

$ file /path/to/program-with-dwarf
/path/to/program-with-dwarf: ELF 64-bit LSB pie executable, ... with debug_info, not stripped

The exact file output depends on the binary. If it says that debug information is absent, rebuild with debug information and use that output. The tool is a DWARF location report, so a stripped or non-DWARF input cannot answer the question you have in mind.

2. Print the baseline coverage report

Pass one filename as the final argument:

$ llvm-locstats-18 /path/to/program-with-dwarf

The report groups DIEs by the proportion of their scope covered by location information. The 0% row means no location information. The 100% row means location information covers every code-section byte in the variable or parameter's scope. The ranges between them are half-open buckets, so [50%,60%) includes 50% but not 60%.

A typical report has this shape, with values determined by the input:

=================================================
          Debug Location Statistics
=================================================
      cov%          samples       percentage(~)
-------------------------------------------------
   0%                    1              16%
   (0%,10%)              0               0%
   [50%,60%)             1              16%
   100%                  3              50%
=================================================
-the number of debug variables processed: 6
-PC ranges covered: 81%
-------------------------------------------------
-total availability: 83%
=================================================

The abbreviated sample above omits some rows for readability. Read samples as the count in each coverage bucket, not as a percentage of machine instructions. PC ranges covered describes code-address coverage, while total availability summarises the availability of debug locations. Keep those measures separate when comparing builds.

Checkpoint

Save the report for the build you are evaluating, or at least record the processed-variable count and the two summary percentages. A percentage without its population is easy to misread.

3. Narrow the population when the question is specific

By default, the report covers the debug variables it finds. Use one of these filters when you need a narrower question:

$ llvm-locstats-18 --only-variables /path/to/program-with-dwarf
$ llvm-locstats-18 --only-formal-parameters /path/to/program-with-dwarf

--only-variables limits the calculation to local variables. --only-formal-parameters limits it to formal parameters. These are separate runs, not cumulative switches. If you pass both, the command line expresses two filters at once, but the manpage does not define that combination as a useful reporting mode, so keep the runs separate when producing a comparison.

Do not compare a filtered run with an unfiltered run and call the percentage change a compiler improvement. First make the population, compiler options and input build the same, then change one filter at a time.

4. Decide how to treat entry-value locations

Some DWARF locations contain the debug entry values operation. If those locations should not contribute to your measurement, add the explicit option:

$ llvm-locstats-18 --ignore-debug-entry-values /path/to/program-with-dwarf

Run the baseline and ignored-entry-values reports against the same file. A changed total is expected because you asked for a different population of locations. Record the option alongside the result; otherwise a later report may look like a regression when it is only using a different rule.

5. Compare two builds

To compare debug-location coverage between two files and draw the difference, provide --compare followed by both paths:

$ llvm-locstats-18 --compare /path/to/build-a/program \
    /path/to/build-b/program

The comparison mode requires matplotlib and draws a plot showing the difference in coverage. The two inputs should represent comparable programs, built from the same source and with the same relevant debug settings. If their code or variable populations differ substantially, a visual difference still describes the files, but it is not a clean isolated compiler comparison.

This command may create a plot image in the current working directory. Run it from a disposable report directory if you want to keep generated output separate from your source tree:

$ mkdir -p /tmp/locstats-report
$ cd /tmp/locstats-report
$ llvm-locstats-18 --compare /path/to/build-a/program \
    /path/to/build-b/program

The temporary directory is safe to remove after you have copied out the plot you need. Do not delete a project directory merely to clean up generated output.

6. Handle failures without guessing

The documented exit status is simple: 0 means the input was parsed successfully and 1 means it was not. Capture it directly when using the command in a script:

$ llvm-locstats-18 /path/to/program-with-dwarf
$ status=$?
$ printf 'llvm-locstats status: %s\n' "$status"
llvm-locstats status: 0

A non-zero result is not evidence that coverage is zero. Check the path, file type and presence of DWARF first, then rerun with the exact file that failed. Avoid parsing the human-readable percentages as an API: the report is intended for inspection, and its bucket text is not a substitute for the exit status.

The tool is a wrapper around llvm-dwarfdump. That explains why an input with unexpected or incomplete debug information can fail before producing a useful report. Use llvm-dwarfdump separately when you need to inspect the underlying DWARF, but keep that investigation distinct from the coverage measurement.

Done means

  • You confirmed the versioned executable and selected a file that contains DWARF.
  • You recorded the processed-variable count, PC-range coverage and total availability.
  • You used the variable or parameter filters only when the narrower population matched your question.
  • You recorded whether debug entry-value locations were included.
  • You compared like-for-like builds and kept generated plots out of the source tree.
  • Your automation checks the exit status instead of treating a percentage as success.