diff options
author | Hana Kim <hakim@google.com> | 2018-01-16 15:31:12 -0500 |
---|---|---|
committer | Hyang-Ah Hana Kim <hyangah@gmail.com> | 2018-02-13 19:23:37 +0000 |
commit | dc3bef36354c7977cfd9e4459e1e6f31bc8624a6 (patch) | |
tree | 46b157a5f09ec677b714c10ea01114fdf9865c67 /src/runtime/runtime-gdb_test.go | |
parent | ef175731ffd2eee6b0da5c2eb8dc2590f2641f2f (diff) | |
download | go-dc3bef36354c7977cfd9e4459e1e6f31bc8624a6.tar.gz go-dc3bef36354c7977cfd9e4459e1e6f31bc8624a6.zip |
runtime/gdb: use goroutine atomicstatus to determine the state
Previously find_goroutine determined whether a goroutine is
stopped by checking the sched.sp field. This heuristic doesn't
always hold but causes find_goroutine to return bogus pc/sp
info for running goroutines.
This change uses the atomicstatus bit to determine
the state which is more accurate.
R=go1.11
Change-Id: I537d432d9e0363257120a196ce2ba52da2970f59
Reviewed-on: https://go-review.googlesource.com/49691
Reviewed-by: Austin Clements <austin@google.com>
Diffstat (limited to 'src/runtime/runtime-gdb_test.go')
-rw-r--r-- | src/runtime/runtime-gdb_test.go | 32 |
1 files changed, 28 insertions, 4 deletions
diff --git a/src/runtime/runtime-gdb_test.go b/src/runtime/runtime-gdb_test.go index 5e0508631f..c96bb95222 100644 --- a/src/runtime/runtime-gdb_test.go +++ b/src/runtime/runtime-gdb_test.go @@ -87,13 +87,24 @@ func main() { ptrvar := &strvar slicevar := make([]string, 0, 16) slicevar = append(slicevar, mapvar["abc"]) - fmt.Println("hi") // line 13 + fmt.Println("hi") runtime.KeepAlive(ptrvar) + _ = ptrvar gslice = slicevar runtime.KeepAlive(mapvar) -} +} // END_OF_PROGRAM ` +func lastLine(src []byte) int { + eop := []byte("END_OF_PROGRAM") + for i, l := range bytes.Split(src, []byte("\n")) { + if bytes.Contains(l, eop) { + return i + } + } + return 0 +} + func TestGdbPython(t *testing.T) { testGdbPython(t, false) } @@ -128,11 +139,13 @@ func testGdbPython(t *testing.T, cgo bool) { } buf.WriteString(helloSource) - src := filepath.Join(dir, "main.go") - err = ioutil.WriteFile(src, buf.Bytes(), 0644) + src := buf.Bytes() + + err = ioutil.WriteFile(filepath.Join(dir, "main.go"), src, 0644) if err != nil { t.Fatalf("failed to create file: %v", err) } + nLines := lastLine(src) cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", "a.exe") cmd.Dir = dir @@ -168,9 +181,16 @@ func testGdbPython(t *testing.T, cgo bool) { "-ex", "echo BEGIN goroutine 2 bt\n", "-ex", "goroutine 2 bt", "-ex", "echo END\n", + "-ex", "clear fmt.Println", // clear the previous break point + "-ex", fmt.Sprintf("br main.go:%d", nLines), // new break point at the end of main + "-ex", "c", + "-ex", "echo BEGIN goroutine 1 bt at the end\n", + "-ex", "goroutine 1 bt", + "-ex", "echo END\n", filepath.Join(dir, "a.exe"), } got, _ := exec.Command("gdb", args...).CombinedOutput() + t.Logf("gdb output: %s\n", got) firstLine := bytes.SplitN(got, []byte("\n"), 2)[0] if string(firstLine) != "Loading Go Runtime support." { @@ -232,6 +252,10 @@ func testGdbPython(t *testing.T, cgo bool) { if bl := blocks["goroutine 2 bt"]; !btGoroutine2Re.MatchString(bl) { t.Fatalf("goroutine 2 bt failed: %s", bl) } + btGoroutine1AtTheEndRe := regexp.MustCompile(`(?m)^#0\s+(0x[0-9a-f]+\s+in\s+)?main\.main.+at`) + if bl := blocks["goroutine 1 bt at the end"]; !btGoroutine1AtTheEndRe.MatchString(bl) { + t.Fatalf("goroutine 1 bt at the end failed: %s", bl) + } } const backtraceSource = ` |