Skip to content

Commit

Permalink
pkg/cover: fix concurrent append to slice
Browse files Browse the repository at this point in the history
It's not safe to append to slice from multiple goroutines.
Either using chan or lock can get constant result.
  • Loading branch information
jiangenj committed May 13, 2024
1 parent c46c25b commit 7bc7200
Showing 1 changed file with 51 additions and 29 deletions.
80 changes: 51 additions & 29 deletions pkg/cover/backend/dwarf.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,45 +154,67 @@ func makeDWARFUnsafe(params *dwarfParams) (*Impl, error) {
var allUnits []*CompileUnit
var pcBase uint64
preciseCoverage := true
for _, module := range modules {
errc := make(chan error, 1)
go func() {
info := &symbolInfo{
tracePC: make(map[uint64]bool),
traceCmp: make(map[uint64]bool),
tracePCIdx: make(map[int]bool),
traceCmpIdx: make(map[int]bool),
}
result, err := processModule(params, module, info, target)
type binResult struct {
symbols []*Symbol
coverPoints [2][]uint64
ranges []pcRange
units []*CompileUnit
err error
}
binC := make(chan binResult, len(modules))
wk := func(module *Module) {
res := binResult{}
info := &symbolInfo{
tracePC: make(map[uint64]bool),
traceCmp: make(map[uint64]bool),
tracePCIdx: make(map[int]bool),
traceCmpIdx: make(map[int]bool),
}
result, err := processModule(params, module, info, target)
if err != nil {
res.err = err
binC <- res
return
}
res.symbols = result.Symbols
if module.Name == "" && len(result.CoverPoints[0]) == 0 {
err = fmt.Errorf("%v doesn't contain coverage callbacks (set CONFIG_KCOV=y on linux)", module.Path)
if err != nil {
errc <- err
res.err = err
binC <- res
return
}
allSymbols = append(allSymbols, result.Symbols...)
if module.Name == "" {
pcBase = info.textAddr
}
allCoverPoints[0] = append(allCoverPoints[0], result.CoverPoints[0]...)
allCoverPoints[1] = append(allCoverPoints[1], result.CoverPoints[1]...)
if module.Name == "" && len(result.CoverPoints[0]) == 0 {
err = fmt.Errorf("%v doesn't contain coverage callbacks (set CONFIG_KCOV=y on linux)", module.Path)
}
errc <- err
}()
}
res.coverPoints = result.CoverPoints
ranges, units, err := params.readTextRanges(module)
if err != nil {
return nil, err
}
if err := <-errc; err != nil {
return nil, err
res.err = err
binC <- res
return
}
allRanges = append(allRanges, ranges...)
allUnits = append(allUnits, units...)
res.ranges = ranges
res.units = units
binC <- res
}
for _, module := range modules {
go func(m *Module, w func(m *Module)) {
w(m)
}(module, wk)
if isKcovBrokenInCompiler(params.getCompilerVersion(module.Path)) {
preciseCoverage = false
}
}

for range modules {
result := <-binC
if err := result.err; err != nil {
return nil, err
}
allSymbols = append(allSymbols, result.symbols...)
allCoverPoints[0] = append(allCoverPoints[0], result.coverPoints[0]...)
allCoverPoints[1] = append(allCoverPoints[1], result.coverPoints[1]...)
allRanges = append(allRanges, result.ranges...)
allUnits = append(allUnits, result.units...)
}
sort.Slice(allSymbols, func(i, j int) bool {
return allSymbols[i].Start < allSymbols[j].Start
})
Expand Down

0 comments on commit 7bc7200

Please sign in to comment.