| name | sqlite-with-gcov |
| description | Guidance for compiling SQLite (or similar C projects) with gcov code coverage instrumentation. This skill should be used when tasks involve building software with gcov flags, setting up code coverage instrumentation, or troubleshooting coverage data file generation. Covers gcov path mechanics, build directory considerations, and runtime verification strategies. |
SQLite with gcov Code Coverage
This skill provides guidance for compiling SQLite or similar C/C++ projects with gcov instrumentation for code coverage analysis.
Core Concepts
How gcov Works
gcov generates two types of files:
.gcnofiles: Generated at compile time, contain control flow graph information.gcdafiles: Generated at runtime, contain execution counts
Critical understanding: gcov embeds absolute paths at compile time. The .gcda files are written to paths based on where the source was compiled, NOT where the binary is installed or executed from.
Path Mechanics
When compiling with -fprofile-arcs -ftest-coverage (or --coverage):
- The compiler records the absolute path of each source file
- At runtime,
.gcdafiles are written relative to these embedded paths - Moving or installing the binary does NOT change where coverage data is written
Approach Strategies
Strategy 1: Build in the Final Location
Build directly in the directory where coverage files should be generated:
# If coverage files need to be in /app/sqlite
cd /app/sqlite
tar -xzf sqlite-source.tar.gz --strip-components=1
./configure CFLAGS="-fprofile-arcs -ftest-coverage" LDFLAGS="-lgcov"
make
This ensures .gcno and .gcda files are generated in /app/sqlite.
Strategy 2: Use GCOV_PREFIX Environment Variables
Redirect coverage data output at runtime:
# Set prefix to redirect .gcda files
export GCOV_PREFIX=/app/sqlite
export GCOV_PREFIX_STRIP=3 # Strip N leading path components
# Run the instrumented binary
./sqlite3
GCOV_PREFIX_STRIP removes leading directory components from the embedded path before prepending GCOV_PREFIX.
Strategy 3: Symbolic Links
Create symbolic links from the build directory to the expected location:
ln -s /tmp/build-dir/sqlite /app/sqlite
Step-by-Step Workflow
Determine where coverage files must be generated
- Check test requirements or documentation
- Identify expected
.gcdafile locations
Choose a build strategy based on requirements:
- Build-in-place for simplest setup
- GCOV_PREFIX for installed binaries
- Symbolic links for flexible redirection
Configure and compile with coverage flags
./configure CFLAGS="-fprofile-arcs -ftest-coverage -g -O0" \ LDFLAGS="-lgcov --coverage" makeAlternatively, use the shorthand:
./configure CFLAGS="--coverage" LDFLAGS="--coverage"Verify compilation artifacts
- Check for
.gcnofiles in the build directory - Verify gcov symbols in binary:
nm binary | grep gcov
- Check for
Perform runtime verification (critical step)
- Execute the instrumented binary
- Check for
.gcdafile generation in the expected location - If files appear elsewhere, adjust strategy
Install if needed (after verifying coverage works)
Verification Checklist
Compile-Time Verification
-
.gcnofiles exist in build directory - Binary contains gcov symbols (
nm <binary> | grep gcov) - No compilation errors related to coverage flags
Runtime Verification (Critical)
- Run the instrumented binary with a simple command
- Locate where
.gcdafiles are generated - Confirm
.gcdafiles appear in the expected location - If location is wrong, adjust build strategy before proceeding
Post-Installation Verification
- Installed binary still generates coverage data
- Coverage data is accessible for analysis
-
gcovcan process the.gcnoand.gcdafiles together
Common Pitfalls
1. Embedded Path Mismatch
Problem: Building in /tmp/build then installing to /app/sqlite - coverage data still writes to /tmp/build.
Solution: Build in the final location OR use GCOV_PREFIX environment variables.
2. Temporary Build Directory
Problem: Building in /tmp/ which may be cleaned up, losing .gcno files needed for coverage analysis.
Solution: Build in a persistent directory or copy .gcno files to a permanent location.
3. Incomplete Verification
Problem: Verifying only compilation (checking .gcno files exist) without testing runtime behavior.
Solution: Always run the binary and verify .gcda files are generated in the correct location before declaring success.
4. Missing gcno Files
Problem: .gcda files exist but gcov cannot analyze them without corresponding .gcno files.
Solution: Keep .gcno files accessible. They must be in the same directory structure as .gcda files for analysis.
5. PATH Configuration
Problem: Adding to ~/.bashrc doesn't affect all execution contexts.
Solution: Set PATH in the same shell session or use absolute paths. For persistent configuration, verify it applies to the test environment.
6. Optimization Interference
Problem: High optimization levels (-O2, -O3) can cause inaccurate coverage due to inlining and code reorganization.
Solution: Use -O0 or -Og with coverage builds for accurate results.
Debugging Coverage Issues
If .gcda files are not appearing where expected:
Find where they ARE being generated:
find / -name "*.gcda" 2>/dev/nullCheck embedded paths in the binary:
strings <binary> | grep -E "\.gcda|\.gcno"Verify gcov runtime is linked:
ldd <binary> | grep gcovCheck for write permission issues:
# Ensure the target directory is writable touch /expected/path/test.gcda && rm /expected/path/test.gcda
Environment Variables Reference
| Variable | Purpose |
|---|---|
GCOV_PREFIX |
Prepend this path to all coverage file output |
GCOV_PREFIX_STRIP |
Remove N leading path components before applying prefix |
GCOV_ERROR_FILE |
Redirect gcov error messages to a file |
Key Principles
- Understand path embedding: gcov paths are set at compile time, not runtime
- Verify runtime behavior: Compilation success does not guarantee correct coverage setup
- Test before declaring done: Run the binary and check
.gcdafile locations - Keep artifacts together:
.gcnoand.gcdafiles must be accessible for analysis - Use persistent directories: Avoid
/tmp/for builds when coverage data must persist