Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

builders/cover: register coverage without changing line numbers #2993

Merged
merged 1 commit into from
Nov 10, 2021

Conversation

robfig
Copy link
Contributor

@robfig robfig commented Oct 30, 2021

This copies in Go's cmd/internal/edit package for bytebuffer-based
editing.

Fixes #2990

@google-cla google-cla bot added the cla: yes label Oct 30, 2021
@robfig robfig force-pushed the issue2990 branch 2 times, most recently from b0fe057 to 6fd9aa1 Compare October 31, 2021 17:23
go/tools/builders/cover.go Outdated Show resolved Hide resolved
The coverage support in the builder works in the following way:

1. Run `go tool cover` to create an instrumented source file, for example:

    ```
    $ go test -work -cover database/sql
    WORK=/var/folders/yf/4v4h0_t53h30t_8vc90d1gx40000gp/T/go-build105184680/

    $ find $WORK -name *cover.go
    ...

    $ less /var/folders/yf/4v4h0_t53h30t_8vc90d1gx40000gp/T/go-build105184680//b059/sql.cover.go
    ...
    func Register(name string, driver driver.Driver) {GoCover_2_343132323961636265643234.Count[0] = 1;
            driversMu.Lock()
            defer driversMu.Unlock()
            if driver == nil {GoCover_2_343132323961636265643234.Count[3] = 1;
                    panic("sql: Register driver is nil")
            }
            GoCover_2_343132323961636265643234.Count[1] = 1;if _, dup := drivers[name]; dup {GoCover_2_343132323961636265643234.Count[4] = 1;
                    panic("sql: Register called twice for driver " + name)
            }
            GoCover_2_343132323961636265643234.Count[2] = 1;drivers[name] = driver
    }

    ...
    // appended to end of file
    var GoCover_2_343132323961636265643234 = struct {
            Count     [727]uint32
            Pos       [3 * 727]uint32
            NumStmt   [727]uint16
    } {
    ...
    ```

2. Register each file's coverage (above, `GoCover_2_343132323961636265643234`) with
   [coverdata](https://pkg.go.dev/github.com/bazelbuild/rules_go@v0.29.0/go/tools/coverdata).
   This requires adding or updating an import for that package and calling `RegisterFile` in `init()`.
   This is done by using `go/parser` and `go/ast` to modify the AST and `go/format` to print it
   back out to the instrumented source file.

The problem is that this changes line numbers, resulting in panics
that no longer identify the correct stack trace.

`go tool cover` avoids this issue because it places the coverage
variable increments on the same line as control flow branch of
interest to avoid this problem, which it accomplishes by using the
[cmd/internal/edit](https://pkg.go.dev/cmd/internal/edit@go1.17.3)
package.

This change brings that approach to rules_go coverage instrumentation:

1. Copy in the cmd/internal/edit package for bytebuffer-based
   editing.

2. Update the `registerCoverage` step to use that instead of AST
   modifications & `go/format`.

Fixes #2990
@linzhp linzhp merged commit cbaf8c5 into master Nov 10, 2021
@robfig robfig deleted the issue2990 branch November 10, 2021 16:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Coverage instrumentation breaks line debug info
2 participants