blob: d6d00035720155c60e798d23938320137e2acaeb [file] [log] [blame]
Paul Nasrata25af2e2015-01-14 14:32:01 -05001package runtime_test
2
3import (
Austin Clements54568682015-02-16 21:56:10 -05004 "bytes"
Shenghou Ma810a4992015-01-16 01:23:56 -05005 "fmt"
Paul Nasrata25af2e2015-01-14 14:32:01 -05006 "io/ioutil"
7 "os"
8 "os/exec"
9 "path/filepath"
Austin Clements54568682015-02-16 21:56:10 -050010 "regexp"
Shenghou Ma810a4992015-01-16 01:23:56 -050011 "runtime"
Paul Nasrata25af2e2015-01-14 14:32:01 -050012 "testing"
13)
14
15func checkGdbPython(t *testing.T) {
Shenghou Ma1b523382015-02-06 14:33:44 -050016 cmd := exec.Command("gdb", "-nx", "-q", "--batch", "-iex", "python import sys; print('go gdb python support')")
Paul Nasrata25af2e2015-01-14 14:32:01 -050017 out, err := cmd.CombinedOutput()
18
19 if err != nil {
Shenghou Ma810a4992015-01-16 01:23:56 -050020 t.Skipf("skipping due to issue running gdb: %v", err)
Paul Nasrata25af2e2015-01-14 14:32:01 -050021 }
Shenghou Ma810a4992015-01-16 01:23:56 -050022 if string(out) != "go gdb python support\n" {
Paul Nasrata25af2e2015-01-14 14:32:01 -050023 t.Skipf("skipping due to lack of python gdb support: %s", out)
24 }
25}
26
27const helloSource = `
28package main
29import "fmt"
Jan Kratochvil1c82e232015-02-21 18:18:33 +010030func main() {
31 mapvar := make(map[string]string,5)
32 mapvar["abc"] = "def"
33 mapvar["ghi"] = "jkl"
Lee Packhamc45751e2015-03-30 17:36:49 +010034 strvar := "abc"
35 ptrvar := &strvar
36 fmt.Println("hi") // line 10
37 _ = ptrvar
Jan Kratochvil1c82e232015-02-21 18:18:33 +010038}
Paul Nasrata25af2e2015-01-14 14:32:01 -050039`
40
Austin Clements54568682015-02-16 21:56:10 -050041func TestGdbPython(t *testing.T) {
Josh Bleecher Snyder5dbbb772015-02-18 15:29:32 -080042 if runtime.GOOS == "darwin" {
43 t.Skip("gdb does not work on darwin")
44 }
Dave Cheneyc1216c32015-02-26 07:48:50 +110045
Paul Nasrata25af2e2015-01-14 14:32:01 -050046 checkGdbPython(t)
47
48 dir, err := ioutil.TempDir("", "go-build")
49 if err != nil {
50 t.Fatalf("failed to create temp directory: %v", err)
51 }
52 defer os.RemoveAll(dir)
53
54 src := filepath.Join(dir, "main.go")
55 err = ioutil.WriteFile(src, []byte(helloSource), 0644)
56 if err != nil {
57 t.Fatalf("failed to create file: %v", err)
58 }
59
60 cmd := exec.Command("go", "build", "-o", "a.exe")
61 cmd.Dir = dir
62 out, err := cmd.CombinedOutput()
63 if err != nil {
64 t.Fatalf("building source %v\n%s", err, out)
65 }
66
Shenghou Ma810a4992015-01-16 01:23:56 -050067 got, _ := exec.Command("gdb", "-nx", "-q", "--batch", "-iex",
68 fmt.Sprintf("add-auto-load-safe-path %s/src/runtime", runtime.GOROOT()),
Lee Packhamc45751e2015-03-30 17:36:49 +010069 "-ex", "br main.go:10",
Austin Clements54568682015-02-16 21:56:10 -050070 "-ex", "run",
71 "-ex", "echo BEGIN info goroutines\n",
72 "-ex", "info goroutines",
73 "-ex", "echo END\n",
Jan Kratochvil1c82e232015-02-21 18:18:33 +010074 "-ex", "echo BEGIN print mapvar\n",
75 "-ex", "print mapvar",
76 "-ex", "echo END\n",
Lee Packhamc45751e2015-03-30 17:36:49 +010077 "-ex", "echo BEGIN print strvar\n",
78 "-ex", "print strvar",
79 "-ex", "echo END\n",
80 "-ex", "echo BEGIN print ptrvar\n",
81 "-ex", "print ptrvar",
82 "-ex", "echo END\n",
Derek Buitenhuis53840ad2015-04-10 15:13:04 -040083 "-ex", "echo BEGIN goroutine 2 bt\n",
84 "-ex", "goroutine 2 bt",
85 "-ex", "echo END\n",
Paul Nasrata25af2e2015-01-14 14:32:01 -050086 filepath.Join(dir, "a.exe")).CombinedOutput()
Austin Clements54568682015-02-16 21:56:10 -050087
88 firstLine := bytes.SplitN(got, []byte("\n"), 2)[0]
89 if string(firstLine) != "Loading Go Runtime support." {
90 t.Fatalf("failed to load Go runtime support: %s", firstLine)
91 }
92
93 // Extract named BEGIN...END blocks from output
94 partRe := regexp.MustCompile(`(?ms)^BEGIN ([^\n]*)\n(.*?)\nEND`)
95 blocks := map[string]string{}
96 for _, subs := range partRe.FindAllSubmatch(got, -1) {
97 blocks[string(subs[1])] = string(subs[2])
98 }
99
Austin Clements1ab55a32015-02-17 15:01:43 -0500100 infoGoroutinesRe := regexp.MustCompile(`\*\s+\d+\s+running\s+`)
Austin Clements54568682015-02-16 21:56:10 -0500101 if bl := blocks["info goroutines"]; !infoGoroutinesRe.MatchString(bl) {
102 t.Fatalf("info goroutines failed: %s", bl)
Paul Nasrata25af2e2015-01-14 14:32:01 -0500103 }
Jan Kratochvil1c82e232015-02-21 18:18:33 +0100104
105 printMapvarRe := regexp.MustCompile(`\Q = map[string]string = {["abc"] = "def", ["ghi"] = "jkl"}\E$`)
106 if bl := blocks["print mapvar"]; !printMapvarRe.MatchString(bl) {
107 t.Fatalf("print mapvar failed: %s", bl)
108 }
Lee Packhamc45751e2015-03-30 17:36:49 +0100109
110 strVarRe := regexp.MustCompile(`\Q = "abc"\E$`)
111 if bl := blocks["print strvar"]; !strVarRe.MatchString(bl) {
112 t.Fatalf("print strvar failed: %s", bl)
113 }
114
115 if bl := blocks["print ptrvar"]; !strVarRe.MatchString(bl) {
116 t.Fatalf("print ptrvar failed: %s", bl)
117 }
Derek Buitenhuis53840ad2015-04-10 15:13:04 -0400118
119 btGoroutineRe := regexp.MustCompile(`^#0\s+runtime.+at`)
120 if bl := blocks["goroutine 2 bt"]; !btGoroutineRe.MatchString(bl) {
121 t.Fatalf("goroutine 2 bt failed: %s", bl)
122 }
Paul Nasrata25af2e2015-01-14 14:32:01 -0500123}