github.com/haraldrudell/parl@v0.4.176/pruntime/stack-trace.go (about)

     1  /*
     2  © 2022–present Harald Rudell <harald.rudell@gmail.com> (https://haraldrudell.github.io/haraldrudell/)
     3  ISC License
     4  */
     5  
     6  package pruntime
     7  
     8  import (
     9  	"runtime"
    10  )
    11  
    12  const (
    13  	// stack allocation binary growth of this multiple
    14  	allocationStep = 1024
    15  	// increase per step
    16  	multiple = 2
    17  )
    18  
    19  // StackTrace returns [runtime.Stack] after allocating sufficient buffer
    20  //   - if the entire stackTrace is converted to string and split: those substrings
    21  //     will be interned part of the larger stackTrace string causing memory leak, ie.
    22  //     If only a single character is kept, the entire block is kept.
    23  //     This leads to megabytes of memory leaks
    24  //   - StackTrace returns a byte slice for convert smaller indiviual parts
    25  //     to string
    26  //   - the stack trace contains spaces, newlines and tab characters for formatting
    27  //   - the first line is status line
    28  //   - each frame is then two lines:
    29  //   - — a function line with argument values
    30  //   - — a filename line beginning with a tab character and
    31  //     a hexadecimal in-line byte offset
    32  //   - the first line-pair is for the StackTrace function itself
    33  //   - if the executing thread is a goroutine:
    34  //   - — the final two lines is “created by,” ie. the location of the go statement and
    35  //     what thread started the goroutine
    36  //   - — the two preceding lines is the goroutine function
    37  //   - the stack trace has a terminating newline
    38  func StackTrace() (stackTrace []byte) {
    39  	var buf []byte
    40  	var bytesWritten int
    41  	for size := allocationStep; ; size *= multiple {
    42  		buf = make([]byte, size)
    43  		if bytesWritten = runtime.Stack(buf, runtimeStackOnlyThisGoroutine); bytesWritten < size {
    44  			break
    45  		}
    46  	}
    47  	stackTrace = buf[:bytesWritten]
    48  
    49  	return
    50  }