fix #277, fix #260: fix crash

Fix crash because of parallel access to ssa.Program
This commit is contained in:
Denis Isaev 2018-11-10 15:51:59 +03:00 committed by Isaev Denis
parent 952cc0b22e
commit 898ae4d364
5 changed files with 24 additions and 28 deletions

1
.gitignore vendored
View File

@ -3,3 +3,4 @@
/dist/ /dist/
/.idea/ /.idea/
/test/path /test/path
/golangci-lint

View File

@ -1,10 +1,14 @@
test: test:
go install ./cmd/... go build -o golangci-lint ./cmd/golangci-lint
GL_TEST_RUN=1 golangci-lint run -v GL_TEST_RUN=1 ./golangci-lint run -v
GL_TEST_RUN=1 golangci-lint run --fast --no-config -v GL_TEST_RUN=1 ./golangci-lint run --fast --no-config -v
GL_TEST_RUN=1 golangci-lint run --no-config -v GL_TEST_RUN=1 ./golangci-lint run --no-config -v
GL_TEST_RUN=1 go test -v ./... GL_TEST_RUN=1 go test -v ./...
test_race:
go build -race -o golangci-lint ./cmd/golangci-lint
GL_TEST_RUN=1 ./golangci-lint run -v --deadline=5m
test_linters: test_linters:
GL_TEST_RUN=1 go test -v ./test -count 1 -run TestSourcesFromTestdataWithIssuesDir/$T GL_TEST_RUN=1 go test -v ./test -count 1 -run TestSourcesFromTestdataWithIssuesDir/$T

View File

@ -106,7 +106,7 @@ func (m Megacheck) Run(ctx context.Context, lintCtx *linter.Context) ([]result.I
return nil, nil return nil, nil
} }
issues := runMegacheck(lintCtx.Program, lintCtx.SSAProgram, lintCtx.LoaderConfig, issues := runMegacheck(lintCtx.Program, lintCtx.MegacheckSSAProgram, lintCtx.LoaderConfig,
m.StaticcheckEnabled, m.GosimpleEnabled, m.UnusedEnabled, lintCtx.Settings().Unused.CheckExported) m.StaticcheckEnabled, m.GosimpleEnabled, m.UnusedEnabled, lintCtx.Settings().Unused.CheckExported)
if len(issues) == 0 { if len(issues) == 0 {
return nil, nil return nil, nil

View File

@ -17,7 +17,8 @@ type Context struct {
LoaderConfig *loader.Config // deprecated, don't use for new linters LoaderConfig *loader.Config // deprecated, don't use for new linters
Program *loader.Program // deprecated, use Packages for new linters Program *loader.Program // deprecated, use Packages for new linters
SSAProgram *ssa.Program SSAProgram *ssa.Program // for unparam and interfacer: they don't change it
MegacheckSSAProgram *ssa.Program // for megacheck: it modifies ssa program
Cfg *config.Config Cfg *config.Config
ASTCache *astcache.Cache ASTCache *astcache.Cache

View File

@ -126,13 +126,16 @@ func (cl ContextLoader) makeFakeLoaderProgram(pkgs []*packages.Package) *loader.
} }
} }
func (cl ContextLoader) buildSSAProgram(pkgs []*packages.Package) *ssa.Program { func (cl ContextLoader) buildSSAProgram(pkgs []*packages.Package, name string) *ssa.Program {
startedAt := time.Now() startedAt := time.Now()
var pkgsBuiltDuration time.Duration
defer func() { defer func() {
cl.log.Infof("SSA repr building took %s", time.Since(startedAt)) cl.log.Infof("SSA %srepr building timing: packages building %s, total %s",
name, pkgsBuiltDuration, time.Since(startedAt))
}() }()
ssaProg, _ := ssautil.Packages(pkgs, ssa.GlobalDebug) ssaProg, _ := ssautil.Packages(pkgs, ssa.GlobalDebug)
pkgsBuiltDuration = time.Since(startedAt)
ssaProg.Build() ssaProg.Build()
return ssaProg return ssaProg
} }
@ -300,24 +303,10 @@ func (cl ContextLoader) Load(ctx context.Context, linters []linter.Config) (*lin
prog = cl.makeFakeLoaderProgram(pkgs) prog = cl.makeFakeLoaderProgram(pkgs)
} }
var ssaProg *ssa.Program var ssaProg, megacheckSSAProg *ssa.Program
if loadMode == packages.LoadAllSyntax { if loadMode == packages.LoadAllSyntax {
ssaProg = cl.buildSSAProgram(pkgs) ssaProg = cl.buildSSAProgram(pkgs, "")
for _, pkginfo := range prog.InitialPackages() { megacheckSSAProg = cl.buildSSAProgram(pkgs, "for megacheck ")
if pkginfo == nil {
cl.log.Infof("Pkginfo is nil")
continue
}
if pkginfo.Pkg == nil {
cl.log.Infof("Pkg %#v: types package is nil", *pkginfo)
continue
}
ssaPkg := ssaProg.Package(pkginfo.Pkg)
if ssaPkg == nil {
cl.log.Infof("Pkg %#v: ssaPkg is nil: %#v", *pkginfo, *pkginfo.Pkg)
continue
}
}
} }
astLog := cl.log.Child("astcache") astLog := cl.log.Child("astcache")
@ -327,9 +316,10 @@ func (cl ContextLoader) Load(ctx context.Context, linters []linter.Config) (*lin
} }
ret := &linter.Context{ ret := &linter.Context{
Packages: pkgs, Packages: pkgs,
Program: prog, Program: prog,
SSAProgram: ssaProg, SSAProgram: ssaProg,
MegacheckSSAProgram: megacheckSSAProg,
LoaderConfig: &loader.Config{ LoaderConfig: &loader.Config{
Cwd: "", // used by depguard and fallbacked to os.Getcwd Cwd: "", // used by depguard and fallbacked to os.Getcwd
Build: nil, // used by depguard and megacheck and fallbacked to build.Default Build: nil, // used by depguard and megacheck and fallbacked to build.Default