runtime: never show system goroutines in traceback

Fixes #9791

g.issystem flag setup races with other code wherever we set it.
Even if we set both in parent goroutine and in the system goroutine,
it is still possible that some other goroutine crashes
before the flag is set. We could pass issystem flag to newproc1,
but we start all goroutines with go nowadays.

Instead look at g.startpc to distinguish system goroutines (similar to topofstack).

Change-Id: Ia3467968dee27fa07d9fecedd4c2b00928f26645
Reviewed-on: https://go-review.googlesource.com/4113
Reviewed-by: Keith Randall <khr@golang.org>
This commit is contained in:
Dmitry Vyukov 2015-02-07 15:31:18 +03:00
parent 84e2567537
commit 59495e8dfd
9 changed files with 61 additions and 14 deletions

View file

@ -10,6 +10,7 @@ import (
"os"
"os/exec"
"path/filepath"
"regexp"
"runtime"
"strings"
"sync"
@ -17,17 +18,20 @@ import (
"text/template"
)
// testEnv excludes GODEBUG from the environment
// to prevent its output from breaking tests that
// are trying to parse other command output.
func testEnv(cmd *exec.Cmd) *exec.Cmd {
if cmd.Env != nil {
panic("environment already set")
}
for _, env := range os.Environ() {
// Exclude GODEBUG from the environment to prevent its output
// from breaking tests that are trying to parse other command output.
if strings.HasPrefix(env, "GODEBUG=") {
continue
}
// Exclude GOTRACEBACK for the same reason.
if strings.HasPrefix(env, "GOTRACEBACK=") {
continue
}
cmd.Env = append(cmd.Env, env)
}
return cmd
@ -217,6 +221,14 @@ func TestMainGoroutineId(t *testing.T) {
}
}
func TestNoHelperGoroutines(t *testing.T) {
output := executeTest(t, noHelperGoroutinesSource, nil)
matches := regexp.MustCompile(`goroutine [0-9]+ \[`).FindAllStringSubmatch(output, -1)
if len(matches) != 1 || matches[0][0] != "goroutine 1 [" {
t.Fatalf("want to see only goroutine 1, see:\n%s", output)
}
}
func TestBreakpoint(t *testing.T) {
output := executeTest(t, breakpointSource, nil)
want := "runtime.Breakpoint()"
@ -431,6 +443,22 @@ func main() {
}
`
const noHelperGoroutinesSource = `
package main
import (
"runtime"
"time"
)
func init() {
i := 0
runtime.SetFinalizer(&i, func(p *int) {})
time.AfterFunc(time.Hour, func() {})
panic("oops")
}
func main() {
}
`
const breakpointSource = `
package main
import "runtime"