1// buildrun -t 45 2 3//go:build !js && !wasip1 4 5// Copyright 2021 The Go Authors. All rights reserved. 6// Use of this source code is governed by a BSD-style 7// license that can be found in the LICENSE file. 8 9// Ensure that runtime traceback does not infinite loop for 10// the testcase below. 11 12package main 13 14import ( 15 "bytes" 16 "io/ioutil" 17 "log" 18 "os" 19 "os/exec" 20 "path/filepath" 21) 22 23const prog = ` 24 25package main 26 27import "context" 28 29var gpi *int 30 31type nAO struct { 32 eE bool 33} 34 35type NAO func(*nAO) 36 37func WEA() NAO { 38 return func(o *nAO) { o.eE = true } 39} 40 41type R struct { 42 cM *CM 43} 44 45type CM int 46 47type A string 48 49func (m *CM) NewA(ctx context.Context, cN string, nn *nAO, opts ...NAO) (*A, error) { 50 for _, o := range opts { 51 o(nn) 52 } 53 s := A("foo") 54 return &s, nil 55} 56 57func (r *R) CA(ctx context.Context, cN string, nn *nAO) (*int, error) { 58 cA, err := r.cM.NewA(ctx, cN, nn, WEA(), WEA()) 59 if err == nil { 60 return nil, err 61 } 62 println(cA) 63 x := int(42) 64 return &x, nil 65} 66 67func main() { 68 c := CM(1) 69 r := R{cM: &c} 70 var ctx context.Context 71 nnr := nAO{} 72 pi, err := r.CA(ctx, "foo", nil) 73 if err != nil { 74 panic("bad") 75 } 76 println(nnr.eE) 77 gpi = pi 78} 79` 80 81func main() { 82 dir, err := ioutil.TempDir("", "46234") 83 if err != nil { 84 log.Fatal(err) 85 } 86 defer os.RemoveAll(dir) 87 88 file := filepath.Join(dir, "main.go") 89 if err := ioutil.WriteFile(file, []byte(prog), 0655); err != nil { 90 log.Fatalf("Write error %v", err) 91 } 92 93 cmd := exec.Command("go", "run", file) 94 output, err := cmd.CombinedOutput() 95 if err == nil { 96 log.Fatalf("Passed, expected an error") 97 } 98 99 want := []byte("nil pointer dereference") 100 if !bytes.Contains(output, want) { 101 log.Fatalf("Unmatched error message %q:\nin\n%s\nError: %v", want, output, err) 102 } 103} 104