Skip to content

Commit 3087e61

Browse files
committed
add script for checking thread locks in funcs that call MakeGitError
1 parent 520a042 commit 3087e61

2 files changed

Lines changed: 70 additions & 0 deletions

File tree

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ build-libgit2:
44
./script/build-libgit2-static.sh
55

66
test: build-libgit2
7+
go run script/check-MakeGitError-thread-lock.go
78
./script/with-static.sh go test ./...
89

910
install: build-libgit2
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package main
2+
3+
import (
4+
"bytes"
5+
"fmt"
6+
"go/ast"
7+
"go/build"
8+
"go/parser"
9+
"go/printer"
10+
"go/token"
11+
"log"
12+
"strings"
13+
)
14+
15+
var (
16+
fset = token.NewFileSet()
17+
)
18+
19+
func main() {
20+
log.SetFlags(0)
21+
22+
bpkg, err := build.ImportDir(".", 0)
23+
if err != nil {
24+
log.Fatal(err)
25+
}
26+
27+
pkgs, err := parser.ParseDir(fset, bpkg.Dir, nil, 0)
28+
if err != nil {
29+
log.Fatal(err)
30+
}
31+
32+
for _, pkg := range pkgs {
33+
if err := checkPkg(pkg); err != nil {
34+
log.Fatal(err)
35+
}
36+
}
37+
if len(pkgs) == 0 {
38+
log.Fatal("No packages to check.")
39+
}
40+
}
41+
42+
var ignoreViolationsInFunc = map[string]bool{
43+
"MakeGitError": true,
44+
"MakeGitError2": true,
45+
}
46+
47+
func checkPkg(pkg *ast.Package) error {
48+
var violations []string
49+
ast.Inspect(pkg, func(node ast.Node) bool {
50+
switch node := node.(type) {
51+
case *ast.FuncDecl:
52+
var b bytes.Buffer
53+
if err := printer.Fprint(&b, fset, node); err != nil {
54+
log.Fatal(err)
55+
}
56+
src := b.String()
57+
58+
if strings.Contains(src, "MakeGitError") && !strings.Contains(src, "runtime.LockOSThread()") && !strings.Contains(src, "defer runtime.UnlockOSThread()") && !ignoreViolationsInFunc[node.Name.Name] {
59+
pos := fset.Position(node.Pos())
60+
violations = append(violations, fmt.Sprintf("%s at %s:%d", node.Name.Name, pos.Filename, pos.Line))
61+
}
62+
}
63+
return true
64+
})
65+
if len(violations) > 0 {
66+
return fmt.Errorf("%d non-thread-locked calls to MakeGitError found. To fix, add the following to each func below that calls MakeGitError, before the cgo call that might produce the error:\n\n\truntime.LockOSThread()\n\tdefer runtime.UnlockOSThread()\n\n%s", len(violations), strings.Join(violations, "\n"))
67+
}
68+
return nil
69+
}

0 commit comments

Comments
 (0)