1// Copyright 2022 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 7import ( 8 "flag" 9 "internal/runtime/exithook" 10 "os" 11 "time" 12 _ "unsafe" 13) 14 15var modeflag = flag.String("mode", "", "mode to run in") 16 17func main() { 18 flag.Parse() 19 switch *modeflag { 20 case "simple": 21 testSimple() 22 case "goodexit": 23 testGoodExit() 24 case "badexit": 25 testBadExit() 26 case "panics": 27 testPanics() 28 case "callsexit": 29 testHookCallsExit() 30 case "exit2": 31 testExit2() 32 default: 33 panic("unknown mode") 34 } 35} 36 37func testSimple() { 38 f1 := func() { println("foo") } 39 f2 := func() { println("bar") } 40 exithook.Add(exithook.Hook{F: f1}) 41 exithook.Add(exithook.Hook{F: f2}) 42 // no explicit call to os.Exit 43} 44 45func testGoodExit() { 46 f1 := func() { println("apple") } 47 f2 := func() { println("orange") } 48 exithook.Add(exithook.Hook{F: f1}) 49 exithook.Add(exithook.Hook{F: f2}) 50 // explicit call to os.Exit 51 os.Exit(0) 52} 53 54func testBadExit() { 55 f1 := func() { println("blog") } 56 f2 := func() { println("blix") } 57 f3 := func() { println("blek") } 58 f4 := func() { println("blub") } 59 f5 := func() { println("blat") } 60 exithook.Add(exithook.Hook{F: f1}) 61 exithook.Add(exithook.Hook{F: f2, RunOnFailure: true}) 62 exithook.Add(exithook.Hook{F: f3}) 63 exithook.Add(exithook.Hook{F: f4, RunOnFailure: true}) 64 exithook.Add(exithook.Hook{F: f5}) 65 os.Exit(1) 66} 67 68func testPanics() { 69 f1 := func() { println("ok") } 70 f2 := func() { panic("BADBADBAD") } 71 f3 := func() { println("good") } 72 exithook.Add(exithook.Hook{F: f1, RunOnFailure: true}) 73 exithook.Add(exithook.Hook{F: f2, RunOnFailure: true}) 74 exithook.Add(exithook.Hook{F: f3, RunOnFailure: true}) 75 os.Exit(0) 76} 77 78func testHookCallsExit() { 79 f1 := func() { println("ok") } 80 f2 := func() { os.Exit(1) } 81 f3 := func() { println("good") } 82 exithook.Add(exithook.Hook{F: f1, RunOnFailure: true}) 83 exithook.Add(exithook.Hook{F: f2, RunOnFailure: true}) 84 exithook.Add(exithook.Hook{F: f3, RunOnFailure: true}) 85 os.Exit(1) 86} 87 88func testExit2() { 89 f1 := func() { time.Sleep(100 * time.Millisecond) } 90 exithook.Add(exithook.Hook{F: f1}) 91 for range 10 { 92 go os.Exit(0) 93 } 94 os.Exit(0) 95} 96