Skip to content

Commit 5c173f5

Browse files
change breakpoint syntax
See #13 The current way to set a breakpoint in godebug is to call the function `godebug.SetTrace()`. I don't like this for various reasons, the top one being that it requires adding an import statement in addition to the breakpoint line. This commit changes the breakpoint marker to this: _ = "breakpoint" This is only one line, is a no-op without godebug, and is unlikely to conflict with users' program code.
1 parent 758f787 commit 5c173f5

34 files changed

+273
-340
lines changed

README.md

+1-5
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,7 @@ For more detail, see the [end of this README](#how-it-works-more-detail).
2323

2424
Insert a breakpoint anywhere in a source file you want to debug:
2525

26-
godebug.SetTrace()
27-
28-
You'll need to import the godebug package in that file, too:
29-
30-
import "github.com/mailgun/godebug/lib"
26+
_ = "breakpoint"
3127

3228
If the breakpoint is in package main and you don't want to examine any imported packages, you can just run:
3329

cmd.go

+1-12
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,7 @@ func checkForUnusedBreakpoints(subcommand string, prog *loader.Program, stdLib m
329329
}
330330
for _, f := range pkg.Files {
331331
ast.Inspect(f, func(node ast.Node) bool {
332-
if isSetTraceCall(node) {
332+
if gen.IsBreakpoint(node) {
333333
pos := prog.Fset.Position(node.Pos())
334334
fmt.Printf("godebug %s: Ignoring breakpoint at %s:%d because package %q has not been flagged for instrumentation. See 'godebug help %s'.\n\n",
335335
subcommand, filepath.Join(pkg.String(), filepath.Base(pos.Filename)), pos.Line, pkg.Pkg.Name(), subcommand)
@@ -340,17 +340,6 @@ func checkForUnusedBreakpoints(subcommand string, prog *loader.Program, stdLib m
340340
}
341341
}
342342

343-
// Copied from gen/gen.go.
344-
func isSetTraceCall(node ast.Node) (b bool) {
345-
defer func() {
346-
if r := recover(); r != nil {
347-
b = false
348-
}
349-
}()
350-
sel := node.(*ast.ExprStmt).X.(*ast.CallExpr).Fun.(*ast.SelectorExpr)
351-
return sel.X.(*ast.Ident).Name == "godebug" && sel.Sel.Name == "SetTrace"
352-
}
353-
354343
func markAlmostAllPackages(prog *loader.Program, stdLib map[string]bool) {
355344
for _, pkg := range prog.AllPackages {
356345
path := pkg.String()

example/main.go

+2-6
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,10 @@
11
package main
22

3-
import (
4-
"fmt"
5-
6-
"github.com/mailgun/godebug/lib"
7-
)
3+
import "fmt"
84

95
func main() {
106
x := mul(1, 2)
11-
godebug.SetTrace()
7+
_ = "breakpoint"
128
x = mul(x, x)
139
if x == 4 {
1410
fmt.Println("It works! x == 4.")

gen/gen.go

+19-7
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,21 @@ func listNewIdentsFromAssign(assign *ast.AssignStmt) (idents []*ast.Ident) {
151151
return
152152
}
153153

154-
func isSetTraceCall(node ast.Node) (b bool) {
154+
func IsBreakpoint(node ast.Node) (b bool) {
155+
return isOldBreakpoint(node) || isNewBreakpoint(node)
156+
}
157+
158+
func isNewBreakpoint(node ast.Node) (b bool) {
159+
defer func() {
160+
if r := recover(); r != nil {
161+
b = false
162+
}
163+
}()
164+
a := node.(*ast.AssignStmt)
165+
return a.Lhs[0].(*ast.Ident).Name == "_" && a.Rhs[0].(*ast.BasicLit).Value == `"breakpoint"`
166+
}
167+
168+
func isOldBreakpoint(node ast.Node) (b bool) {
155169
defer func() {
156170
if r := recover(); r != nil {
157171
b = false
@@ -636,17 +650,15 @@ func (v *visitor) Visit(node ast.Node) ast.Visitor {
636650
}
637651
}
638652

639-
if !isSetTraceCall(node) {
653+
if !IsBreakpoint(node) {
640654
v.stmtBuf = append(v.stmtBuf, newCallStmt(idents.godebug, "Line", ast.NewIdent(idents.ctx), ast.NewIdent(v.scopeVar), newInt(pos2line(node.Pos()))))
641655
}
642656

643657
// Copy the statement into the new block we are building.
644658
if stmt, ok := node.(ast.Stmt); ok {
645-
if isSetTraceCall(node) {
646-
// Rewrite godebug.SetTrace() as godebug.SetTraceGen(ctx)
647-
call := stmt.(*ast.ExprStmt).X.(*ast.CallExpr)
648-
call.Args = []ast.Expr{ast.NewIdent(idents.ctx)}
649-
call.Fun.(*ast.SelectorExpr).Sel.Name = "SetTraceGen"
659+
if IsBreakpoint(node) {
660+
// Rewrite `godebug.SetTrace()` and `_ = "breakpoint"` as `godebug.SetTraceGen(ctx)`.
661+
stmt = astPrintf("godebug.SetTraceGen(ctx)")[0]
650662
}
651663
v.stmtBuf = append(v.stmtBuf, stmt)
652664
}

lib/debug.go

+1-2
Original file line numberDiff line numberDiff line change
@@ -332,8 +332,7 @@ func Defer(c *Context, s *Scope, line int) {
332332
lineWithPrefix(c, s, line, "<Running deferred function>: ")
333333
}
334334

335-
// SetTrace is the entrypoint to the debugger. The code generator converts
336-
// this call to a call to SetTraceGen.
335+
// SetTrace is deprecated. It will be deleted in a future release.
337336
func SetTrace() {
338337
}
339338

testdata/run.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,6 @@ creates:
332332
- $TMP/breakpointInDependency.go
333333

334334
transcript: |
335-
godebug run: Ignoring breakpoint at testpkg/pkg.go:6 because package "testpkg" has not been flagged for instrumentation. See 'godebug help run'.//slashes
335+
godebug run: Ignoring breakpoint at testpkg/pkg.go:4 because package "testpkg" has not been flagged for instrumentation. See 'godebug help run'.//slashes
336336
337337
finished running

testdata/single-file-tests/example-in.go

+2-6
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,10 @@
11
package main
22

3-
import (
4-
"fmt"
5-
6-
"github.com/mailgun/godebug/lib"
7-
)
3+
import "fmt"
84

95
func main() {
106
x := mul(1, 2)
11-
godebug.SetTrace()
7+
_ = "breakpoint"
128
x = mul(x, x)
139
if x == 4 {
1410
fmt.Println("It works! x == 4.")

testdata/single-file-tests/example-out.go

+22-26
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package main
22

33
import (
44
"fmt"
5-
65
"github.com/mailgun/godebug/lib"
76
)
87

@@ -13,27 +12,28 @@ func main() {
1312
if !ok {
1413
return
1514
}
16-
godebug.Line(ctx, example_in_go_scope, 10)
15+
godebug.Line(ctx, example_in_go_scope, 6)
1716
x := mul(1, 2)
1817
scope := example_in_go_scope.EnteringNewChildScope()
1918
scope.Declare("x", &x)
2019
godebug.SetTraceGen(ctx)
21-
godebug.Line(ctx, scope, 12)
20+
godebug.Line(ctx, scope, 8)
21+
2222
x = mul(x, x)
23-
godebug.Line(ctx, scope, 13)
23+
godebug.Line(ctx, scope, 9)
2424
if x == 4 {
25-
godebug.Line(ctx, scope, 14)
25+
godebug.Line(ctx, scope, 10)
2626
fmt.Println("It works! x == 4.")
2727
} else {
28-
godebug.ElseIfSimpleStmt(ctx, scope, 15)
28+
godebug.ElseIfSimpleStmt(ctx, scope, 11)
2929
n := 2
30-
godebug.ElseIfExpr(ctx, scope, 15)
30+
godebug.ElseIfExpr(ctx, scope, 11)
3131
if n == 3 {
32-
godebug.Line(ctx, scope, 16)
32+
godebug.Line(ctx, scope, 12)
3333
fmt.Println("Math is broken. Ah!")
3434
} else {
35-
godebug.Line(ctx, scope, 17)
36-
godebug.Line(ctx, scope, 18)
35+
godebug.Line(ctx, scope, 13)
36+
godebug.Line(ctx, scope, 14)
3737
fmt.Println("What's going on? x ==", x)
3838
}
3939
}
@@ -50,17 +50,17 @@ func add(n, m int) int {
5050
defer godebug.ExitFunc(ctx)
5151
scope := example_in_go_scope.EnteringNewChildScope()
5252
scope.Declare("n", &n, "m", &m)
53-
godebug.Line(ctx, scope, 23)
53+
godebug.Line(ctx, scope, 19)
5454
if n == 0 {
55-
godebug.Line(ctx, scope, 24)
55+
godebug.Line(ctx, scope, 20)
5656
return m
5757
}
58-
godebug.Line(ctx, scope, 26)
58+
godebug.Line(ctx, scope, 22)
5959
if m == 0 {
60-
godebug.Line(ctx, scope, 27)
60+
godebug.Line(ctx, scope, 23)
6161
return n
6262
}
63-
godebug.Line(ctx, scope, 29)
63+
godebug.Line(ctx, scope, 25)
6464
return n + m
6565
}
6666

@@ -75,34 +75,30 @@ func mul(n, m int) int {
7575
defer godebug.ExitFunc(ctx)
7676
scope := example_in_go_scope.EnteringNewChildScope()
7777
scope.Declare("n", &n, "m", &m)
78-
godebug.Line(ctx, scope, 33)
78+
godebug.Line(ctx, scope, 29)
7979
var x int
8080
scope.Declare("x", &x)
8181
{
8282
scope := scope.EnteringNewChildScope()
8383
for i := 0; i < m; i++ {
84-
godebug.Line(ctx, scope, 34)
84+
godebug.Line(ctx, scope, 30)
8585
scope.Declare("i", &i)
86-
godebug.Line(ctx, scope, 35)
86+
godebug.Line(ctx, scope, 31)
8787
x = add(x, m)
8888
}
89-
godebug.Line(ctx, scope, 34)
89+
godebug.Line(ctx, scope, 30)
9090
}
91-
godebug.Line(ctx, scope, 37)
91+
godebug.Line(ctx, scope, 33)
9292
return x
9393
}
9494

9595
var example_in_go_contents = `package main
9696
97-
import (
98-
"fmt"
99-
100-
"github.com/mailgun/godebug/lib"
101-
)
97+
import "fmt"
10298
10399
func main() {
104100
x := mul(1, 2)
105-
godebug.SetTrace()
101+
_ = "breakpoint"
106102
x = mul(x, x)
107103
if x == 4 {
108104
fmt.Println("It works! x == 4.")

testdata/single-file-tests/example-session-list-2.txt

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
1-
// More of the list command.
2-
31
-> x = mul(x, x)
42
(godebug) list
53

64

75
func main() {
86
x := mul(1, 2)
9-
godebug.SetTrace()
7+
_ = "breakpoint"
108
--> x = mul(x, x)
119
if x == 4 {
1210
fmt.Println("It works! x == 4.")

testdata/single-file-tests/example-session-list.txt

+3-5
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
1-
// Using the list command.
2-
31
-> x = mul(x, x)
42
(godebug) list
53

64

75
func main() {
86
x := mul(1, 2)
9-
godebug.SetTrace()
7+
_ = "breakpoint"
108
--> x = mul(x, x)
119
if x == 4 {
1210
fmt.Println("It works! x == 4.")
@@ -19,7 +17,7 @@
1917

2018
func main() {
2119
x := mul(1, 2)
22-
godebug.SetTrace()
20+
_ = "breakpoint"
2321
x = mul(x, x)
2422
--> if x == 4 {
2523
fmt.Println("It works! x == 4.")
@@ -31,7 +29,7 @@
3129
-> } else if n := 2; n == 3 {
3230
(godebug) l
3331

34-
godebug.SetTrace()
32+
_ = "breakpoint"
3533
x = mul(x, x)
3634
if x == 4 {
3735
fmt.Println("It works! x == 4.")

testdata/single-file-tests/recover-in.go

+2-6
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
11
package main
22

3-
import (
4-
"log"
5-
6-
"github.com/mailgun/godebug/lib"
7-
)
3+
import "log"
84

95
func r1() {
106
recover()
@@ -49,7 +45,7 @@ func doNestedRecover(recoverer func()) {
4945
}
5046

5147
func main() {
52-
godebug.SetTrace()
48+
_ = "breakpoint"
5349
doPanic(r1)
5450
doPanic(r2)
5551
doPanic(r3)

0 commit comments

Comments
 (0)