---
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:
- `.gcno` files: Generated at **compile time**, contain control flow graph information
- `.gcda` files: 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`):
1. The compiler records the absolute path of each source file
2. At runtime, `.gcda` files are written relative to these embedded paths
3. 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:

```bash
# 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:

```bash
# 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:

```bash
ln -s /tmp/build-dir/sqlite /app/sqlite
```

## Step-by-Step Workflow

1. **Determine where coverage files must be generated**
   - Check test requirements or documentation
   - Identify expected `.gcda` file locations

2. **Choose a build strategy** based on requirements:
   - Build-in-place for simplest setup
   - GCOV_PREFIX for installed binaries
   - Symbolic links for flexible redirection

3. **Configure and compile with coverage flags**
   ```bash
   ./configure CFLAGS="-fprofile-arcs -ftest-coverage -g -O0" \
               LDFLAGS="-lgcov --coverage"
   make
   ```

   Alternatively, use the shorthand:
   ```bash
   ./configure CFLAGS="--coverage" LDFLAGS="--coverage"
   ```

4. **Verify compilation artifacts**
   - Check for `.gcno` files in the build directory
   - Verify gcov symbols in binary: `nm binary | grep gcov`

5. **Perform runtime verification** (critical step)
   - Execute the instrumented binary
   - Check for `.gcda` file generation in the expected location
   - If files appear elsewhere, adjust strategy

6. **Install if needed** (after verifying coverage works)

## Verification Checklist

### Compile-Time Verification
- [ ] `.gcno` files 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 `.gcda` files are generated
- [ ] Confirm `.gcda` files 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
- [ ] `gcov` can process the `.gcno` and `.gcda` files 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:

1. **Find where they ARE being generated**:
   ```bash
   find / -name "*.gcda" 2>/dev/null
   ```

2. **Check embedded paths in the binary**:
   ```bash
   strings <binary> | grep -E "\.gcda|\.gcno"
   ```

3. **Verify gcov runtime is linked**:
   ```bash
   ldd <binary> | grep gcov
   ```

4. **Check for write permission issues**:
   ```bash
   # 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

1. **Understand path embedding**: gcov paths are set at compile time, not runtime
2. **Verify runtime behavior**: Compilation success does not guarantee correct coverage setup
3. **Test before declaring done**: Run the binary and check `.gcda` file locations
4. **Keep artifacts together**: `.gcno` and `.gcda` files must be accessible for analysis
5. **Use persistent directories**: Avoid `/tmp/` for builds when coverage data must persist
