Source file src/runtime/testdata/testgoroutineleakprofile/goker/cockroach9935.go

     1  // Copyright 2025 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a MIT
     3  // license that can be found in the LICENSE file.
     4  
     5  /*
     6   * Project: cockroach
     7   * Issue or PR  : https://github.com/cockroachdb/cockroach/pull/9935
     8   * Buggy version: 4df302cc3f03328395dc3fefbfba58b7718e4f2f
     9   * fix commit-id: ed6a100ba38dd51b0888b9a3d3ac6bdbb26c528c
    10   * Flaky: 100/100
    11   * Description: This leak is caused by acquiring l.mu.Lock() twice. The fix is
    12   * to release l.mu.Lock() before acquiring l.mu.Lock for the second time.
    13   */
    14  package main
    15  
    16  import (
    17  	"errors"
    18  	"math/rand"
    19  	"os"
    20  	"runtime/pprof"
    21  	"sync"
    22  	"time"
    23  )
    24  
    25  func init() {
    26  	register("Cockroach9935", Cockroach9935)
    27  }
    28  
    29  type loggingT_cockroach9935 struct {
    30  	mu sync.Mutex
    31  }
    32  
    33  func (l *loggingT_cockroach9935) outputLogEntry() {
    34  	l.mu.Lock()
    35  	if err := l.createFile(); err != nil {
    36  		l.exit(err)
    37  	}
    38  	l.mu.Unlock()
    39  }
    40  
    41  func (l *loggingT_cockroach9935) createFile() error {
    42  	if rand.Intn(8)%4 > 0 {
    43  		return errors.New("")
    44  	}
    45  	return nil
    46  }
    47  
    48  func (l *loggingT_cockroach9935) exit(err error) {
    49  	l.mu.Lock() // Blocked forever
    50  	defer l.mu.Unlock()
    51  }
    52  
    53  // Example of goroutine leak trace:
    54  //
    55  // G1
    56  //----------------------------
    57  // l.outputLogEntry()
    58  // l.mu.Lock()
    59  // l.createFile()
    60  // l.exit()
    61  // l.mu.Lock()
    62  //-----------G1 leaks---------
    63  
    64  func Cockroach9935() {
    65  	prof := pprof.Lookup("goroutineleak")
    66  	defer func() {
    67  		time.Sleep(100 * time.Millisecond)
    68  		prof.WriteTo(os.Stdout, 2)
    69  	}()
    70  
    71  	for i := 0; i < 100; i++ {
    72  		go func() {
    73  			l := &loggingT_cockroach9935{}
    74  			go l.outputLogEntry() // G1
    75  		}()
    76  	}
    77  }
    78  

View as plain text