Golang 1.12.5版本中关于`-coverpkg`的问题#30374仍然存在

Golang 1.12.5版本中关于-coverpkg的问题#30374仍然存在 我遇到了与 https://github.com/golang/go/issues/30374 中报告相同的错误,该问题本应在 1.12.5 版本中修复~~,但无法在那里评论~~当然我可以评论,现在已经评论了,所以这个帖子已过时 - 抱歉造成干扰。

$ go version
go version go1.12.5 linux/amd64
`go env` 输出
$ go env
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/simon/.cache/go-build"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/media/ext4_data/Coding/go"
GOPROXY=""
GORACE=""
GOROOT="/media/ext4_data/Linux/source/go"
GOTMPDIR=""
GOTOOLDIR="/media/ext4_data/Linux/source/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/home/simon/tmp/syncthing/go.mod"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build248314634=/tmp/go-build -gno-record-gcc-switches"

使用 -coverpkg 对所有包运行所有测试

git clone https://github.com/syncthing/syncthing.git
cd syncthing
go test -short -coverprofile coverage.out -coverpkg ./cmd/...,./lib/... ./cmd/... ./lib/...

结果出现与之前报告相同的错误:

2019/05/15 16:02:50 duplicate symbol go.constinfo.main (types 45 and 45) in github.com/syncthing/syncthing/cmd/strelaypoolsrv and /home/simon/.cache/go-build/87/87afda35dba0b8de44e2f9d449eda7ce4caef7ed781612883b4e457eab1ee3d5-d(_go_.o)

仅使用 ./... 也会出现相同问题。我彻底清理了 ~/.cache/go-build,但没有任何改变。


更多关于Golang 1.12.5版本中关于`-coverpkg`的问题#30374仍然存在的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于Golang 1.12.5版本中关于`-coverpkg`的问题#30374仍然存在的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在Go 1.12.5版本中,-coverpkg标志确实存在重复符号的问题,这是由编译器在代码覆盖率检测时处理包依赖关系的方式导致的。当多个包共享相同的常量或函数时,覆盖率检测可能会生成重复的符号定义。

以下是重现该问题的简化示例:

// main.go
package main

import "fmt"

const Version = "1.0.0"

func main() {
    fmt.Println("Version:", Version)
}
// helper/helper.go
package helper

import "fmt"

const Version = "1.0.0"

func PrintVersion() {
    fmt.Println("Helper Version:", Version)
}
// helper/helper_test.go
package helper

import "testing"

func TestPrintVersion(t *testing.T) {
    PrintVersion()
}

使用覆盖率测试命令:

go test -coverprofile=coverage.out -coverpkg=./...,./helper/... ./... ./helper/...

这会触发类似的重复符号错误:

duplicate symbol go.constinfo.Version (types 45 and 45) in main and helper

解决方案:

  1. 使用更精确的包路径,避免包路径重叠:
go test -coverprofile=coverage.out -coverpkg=./helper ./helper
  1. 分别测试每个包,然后合并覆盖率结果:
go test -coverprofile=cmd.out -coverpkg=./cmd/... ./cmd/...
go test -coverprofile=lib.out -coverpkg=./lib/... ./lib/...
  1. 使用工具合并覆盖率文件
gocovmerge cmd.out lib.out > coverage.out

对于syncthing项目,建议的测试命令:

# 分别测试cmd和lib目录
go test -short -coverprofile=cmd.out -coverpkg=./cmd/... ./cmd/...
go test -short -coverprofile=lib.out -coverpkg=./lib/... ./lib/...

# 合并覆盖率结果(需要安装gocovmerge)
go get github.com/wadey/gocovmerge
gocovmerge cmd.out lib.out > coverage.out

这个问题的根本修复需要在Go编译器中实现,但在当前版本中,通过分离测试目标可以避免重复符号错误。

回到顶部