465b2d709644eed5c5143bcfbbc4ff416d145ece
[platform/upstream/gcc.git] / libgo / go / runtime / crash_test.go
1 // Copyright 2012 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 package runtime_test
6
7 import (
8         "io/ioutil"
9         "os"
10         "os/exec"
11         "path/filepath"
12         "runtime"
13         "testing"
14         "text/template"
15 )
16
17 type crashTest struct {
18         Cgo bool
19 }
20
21 // This test is a separate program, because it is testing
22 // both main (m0) and non-main threads (m).
23
24 func testCrashHandler(t *testing.T, ct *crashTest) {
25         if runtime.GOOS == "freebsd" || runtime.GOOS == "netbsd" {
26                 // TODO(brainman): do not know why this test fails on freebsd
27                 // TODO(jsing): figure out why this causes delayed failures
28                 // on NetBSD - http://golang.org/issue/3954
29                 t.Logf("skipping test on %q", runtime.GOOS)
30                 return
31         }
32
33         st := template.Must(template.New("crashSource").Parse(crashSource))
34
35         dir, err := ioutil.TempDir("", "go-build")
36         if err != nil {
37                 t.Fatalf("failed to create temp directory: %v", err)
38         }
39         defer os.RemoveAll(dir)
40
41         src := filepath.Join(dir, "main.go")
42         f, err := os.Create(src)
43         if err != nil {
44                 t.Fatalf("failed to create %v: %v", src, err)
45         }
46         err = st.Execute(f, ct)
47         if err != nil {
48                 f.Close()
49                 t.Fatalf("failed to execute template: %v", err)
50         }
51         f.Close()
52
53         got, err := exec.Command("go", "run", src).CombinedOutput()
54         if err != nil {
55                 t.Fatalf("program exited with error: %v\n%v", err, string(got))
56         }
57         want := "main: recovered done\nnew-thread: recovered done\nsecond-new-thread: recovered done\nmain-again: recovered done\n"
58         if string(got) != string(want) {
59                 t.Fatalf("expected %q, but got %q", string(want), string(got))
60         }
61 }
62
63 func TestCrashHandler(t *testing.T) {
64         testCrashHandler(t, &crashTest{Cgo: false})
65 }
66
67 const crashSource = `
68 package main
69
70 import (
71         "fmt"
72         "runtime"
73 )
74
75 {{if .Cgo}}
76 import "C"
77 {{end}}
78
79 func test(name string) {
80         defer func() {
81                 if x := recover(); x != nil {
82                         fmt.Printf(" recovered")
83                 }
84                 fmt.Printf(" done\n")
85         }()
86         fmt.Printf("%s:", name)
87         var s *string
88         _ = *s
89         fmt.Print("SHOULD NOT BE HERE")
90 }
91
92 func testInNewThread(name string) {
93         c := make(chan bool)
94         go func() {
95                 runtime.LockOSThread()
96                 test(name)
97                 c <- true
98         }()
99         <-c
100 }
101
102 func main() {
103         runtime.LockOSThread()
104         test("main")
105         testInNewThread("new-thread")
106         testInNewThread("second-new-thread")
107         test("main-again")
108 }
109 `