lab.nexedi.com/kirr/go123@v0.0.0-20240207185015-8299741fa871/xruntime/xruntime.go (about)

     1  // Copyright (C) 2015-2019  Nexedi SA and Contributors.
     2  //                          Kirill Smelkov <kirr@nexedi.com>
     3  //
     4  // This program is free software: you can Use, Study, Modify and Redistribute
     5  // it under the terms of the GNU General Public License version 3, or (at your
     6  // option) any later version, as published by the Free Software Foundation.
     7  //
     8  // You can also Link and Combine this program with other software covered by
     9  // the terms of any of the Free Software licenses or any of the Open Source
    10  // Initiative approved licenses and Convey the resulting work. Corresponding
    11  // source of such a combination shall include the source code for all other
    12  // software used.
    13  //
    14  // This program is distributed WITHOUT ANY WARRANTY; without even the implied
    15  // warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    16  //
    17  // See COPYING file for full licensing terms.
    18  // See https://www.nexedi.com/licensing for rationale and options.
    19  
    20  // Package xruntime provides addons to standard package runtime.
    21  package xruntime
    22  
    23  import (
    24  	"runtime"
    25  )
    26  
    27  // Traceback returns current calling traceback as []runtime.Frame .
    28  //
    29  // nskip meaning: the same as in runtime.Callers() .
    30  func Traceback(nskip int) []runtime.Frame {
    31  	// all callers
    32  	var pcv = []uintptr{0}
    33  	for {
    34  		pcv = make([]uintptr, 2*len(pcv))
    35  		n := runtime.Callers(nskip+1, pcv)
    36  		if n < len(pcv) {
    37  			pcv = pcv[:n]
    38  			break
    39  		}
    40  	}
    41  
    42  	// pcv -> frames
    43  	framev := make([]runtime.Frame, 0, len(pcv))
    44  	frames := runtime.CallersFrames(pcv)
    45  	for more := true; more; {
    46  		var frame runtime.Frame
    47  		frame, more = frames.Next()
    48  		framev = append(framev, frame)
    49  	}
    50  
    51  	return framev
    52  }