• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2015 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
5package main
6
7/*
8void foo1(void) {}
9void foo2(void* p) {}
10*/
11import "C"
12import (
13	"fmt"
14	"os"
15	"runtime"
16	"strconv"
17	"time"
18	"unsafe"
19)
20
21func init() {
22	register("CgoSignalDeadlock", CgoSignalDeadlock)
23	register("CgoTraceback", CgoTraceback)
24	register("CgoCheckBytes", CgoCheckBytes)
25}
26
27func CgoSignalDeadlock() {
28	runtime.GOMAXPROCS(100)
29	ping := make(chan bool)
30	go func() {
31		for i := 0; ; i++ {
32			runtime.Gosched()
33			select {
34			case done := <-ping:
35				if done {
36					ping <- true
37					return
38				}
39				ping <- true
40			default:
41			}
42			func() {
43				defer func() {
44					recover()
45				}()
46				var s *string
47				*s = ""
48				fmt.Printf("continued after expected panic\n")
49			}()
50		}
51	}()
52	time.Sleep(time.Millisecond)
53	start := time.Now()
54	var times []time.Duration
55	n := 64
56	if os.Getenv("RUNTIME_TEST_SHORT") != "" {
57		n = 16
58	}
59	for i := 0; i < n; i++ {
60		go func() {
61			runtime.LockOSThread()
62			select {}
63		}()
64		go func() {
65			runtime.LockOSThread()
66			select {}
67		}()
68		time.Sleep(time.Millisecond)
69		ping <- false
70		select {
71		case <-ping:
72			times = append(times, time.Since(start))
73		case <-time.After(time.Second):
74			fmt.Printf("HANG 1 %v\n", times)
75			return
76		}
77	}
78	ping <- true
79	select {
80	case <-ping:
81	case <-time.After(time.Second):
82		fmt.Printf("HANG 2 %v\n", times)
83		return
84	}
85	fmt.Printf("OK\n")
86}
87
88func CgoTraceback() {
89	C.foo1()
90	buf := make([]byte, 1)
91	runtime.Stack(buf, true)
92	fmt.Printf("OK\n")
93}
94
95func CgoCheckBytes() {
96	try, _ := strconv.Atoi(os.Getenv("GO_CGOCHECKBYTES_TRY"))
97	if try <= 0 {
98		try = 1
99	}
100	b := make([]byte, 1e6*try)
101	start := time.Now()
102	for i := 0; i < 1e3*try; i++ {
103		C.foo2(unsafe.Pointer(&b[0]))
104		if time.Since(start) > time.Second {
105			break
106		}
107	}
108}
109