github.com/haraldrudell/parl@v0.4.176/pruntime/invocation-id.go (about)

     1  /*
     2  © 2021–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/debug"
    10  	"strings"
    11  )
    12  
    13  /*
    14  A stack has a leading line with go routine ID, then two lines per frame:
    15  goroutine 1 [running]:
    16  runtime/debug.Stack(0x1, 0x1, 0x2)
    17  
    18  	/usr/local/Cellar/go/1.16.6/libexec/src/runtime/debug/stack.go:24 +0x9f
    19  */
    20  const (
    21  	// the number of lines debug.Stack produces for each stack frame
    22  	linesPerStackFrame = 2
    23  	// skip debug.Stack, that includes itself, and the Invocation stack frames
    24  	skipFrames = 2
    25  )
    26  
    27  // Invocation returns an invocation stack trace for debug printing, empty string on troubles.
    28  // The result is similar to the output from debug.Stack, but has some stack frames removed.
    29  // tabs are replaced by two spaces.
    30  // stackFramesToSkip 0 means first frame will be the caller of Invocation
    31  // "goroutine 1 [running]:\ngithub.com/haraldrudell/parl/mains.(*Executable).AddErr(0x1809300, 0x158b620, 0xc000183800, 0x1) mains.(*Executable).AddErr-executable.go:302…"
    32  func Invocation(stackFramesToSkip int) (stackTrace string) {
    33  	if stackFramesToSkip < 0 {
    34  		stackFramesToSkip = 0
    35  	}
    36  
    37  	// remove the first few stack frames
    38  	stackBytes := debug.Stack()
    39  	stackString := string(stackBytes)
    40  	stackTraceLines := strings.Split(stackString, "\n")
    41  	linesToSkip := (stackFramesToSkip + skipFrames) * linesPerStackFrame
    42  	copy(stackTraceLines[1:], stackTraceLines[1+linesToSkip:])
    43  	stackTraceLines = stackTraceLines[:len(stackTraceLines)-linesToSkip]
    44  	stackTrace = strings.Join(stackTraceLines, "\n")
    45  
    46  	return strings.ReplaceAll(stackTrace, "\t", "\x20\x20")
    47  }