mirror of
				https://github.com/k3s-io/kubernetes.git
				synced 2025-10-31 13:50:01 +00:00 
			
		
		
		
	until stable: pin-dependency, update-vendor, update-bazel, lint-dep
This commit is contained in:
		
							
								
								
									
										102
									
								
								vendor/github.com/go-errors/errors/stackframe.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										102
									
								
								vendor/github.com/go-errors/errors/stackframe.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,102 @@ | ||||
| package errors | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"fmt" | ||||
| 	"io/ioutil" | ||||
| 	"runtime" | ||||
| 	"strings" | ||||
| ) | ||||
|  | ||||
| // A StackFrame contains all necessary information about to generate a line | ||||
| // in a callstack. | ||||
| type StackFrame struct { | ||||
| 	// The path to the file containing this ProgramCounter | ||||
| 	File string | ||||
| 	// The LineNumber in that file | ||||
| 	LineNumber int | ||||
| 	// The Name of the function that contains this ProgramCounter | ||||
| 	Name string | ||||
| 	// The Package that contains this function | ||||
| 	Package string | ||||
| 	// The underlying ProgramCounter | ||||
| 	ProgramCounter uintptr | ||||
| } | ||||
|  | ||||
| // NewStackFrame popoulates a stack frame object from the program counter. | ||||
| func NewStackFrame(pc uintptr) (frame StackFrame) { | ||||
|  | ||||
| 	frame = StackFrame{ProgramCounter: pc} | ||||
| 	if frame.Func() == nil { | ||||
| 		return | ||||
| 	} | ||||
| 	frame.Package, frame.Name = packageAndName(frame.Func()) | ||||
|  | ||||
| 	// pc -1 because the program counters we use are usually return addresses, | ||||
| 	// and we want to show the line that corresponds to the function call | ||||
| 	frame.File, frame.LineNumber = frame.Func().FileLine(pc - 1) | ||||
| 	return | ||||
|  | ||||
| } | ||||
|  | ||||
| // Func returns the function that contained this frame. | ||||
| func (frame *StackFrame) Func() *runtime.Func { | ||||
| 	if frame.ProgramCounter == 0 { | ||||
| 		return nil | ||||
| 	} | ||||
| 	return runtime.FuncForPC(frame.ProgramCounter) | ||||
| } | ||||
|  | ||||
| // String returns the stackframe formatted in the same way as go does | ||||
| // in runtime/debug.Stack() | ||||
| func (frame *StackFrame) String() string { | ||||
| 	str := fmt.Sprintf("%s:%d (0x%x)\n", frame.File, frame.LineNumber, frame.ProgramCounter) | ||||
|  | ||||
| 	source, err := frame.SourceLine() | ||||
| 	if err != nil { | ||||
| 		return str | ||||
| 	} | ||||
|  | ||||
| 	return str + fmt.Sprintf("\t%s: %s\n", frame.Name, source) | ||||
| } | ||||
|  | ||||
| // SourceLine gets the line of code (from File and Line) of the original source if possible. | ||||
| func (frame *StackFrame) SourceLine() (string, error) { | ||||
| 	data, err := ioutil.ReadFile(frame.File) | ||||
|  | ||||
| 	if err != nil { | ||||
| 		return "", New(err) | ||||
| 	} | ||||
|  | ||||
| 	lines := bytes.Split(data, []byte{'\n'}) | ||||
| 	if frame.LineNumber <= 0 || frame.LineNumber >= len(lines) { | ||||
| 		return "???", nil | ||||
| 	} | ||||
| 	// -1 because line-numbers are 1 based, but our array is 0 based | ||||
| 	return string(bytes.Trim(lines[frame.LineNumber-1], " \t")), nil | ||||
| } | ||||
|  | ||||
| func packageAndName(fn *runtime.Func) (string, string) { | ||||
| 	name := fn.Name() | ||||
| 	pkg := "" | ||||
|  | ||||
| 	// The name includes the path name to the package, which is unnecessary | ||||
| 	// since the file name is already included.  Plus, it has center dots. | ||||
| 	// That is, we see | ||||
| 	//  runtime/debug.*T·ptrmethod | ||||
| 	// and want | ||||
| 	//  *T.ptrmethod | ||||
| 	// Since the package path might contains dots (e.g. code.google.com/...), | ||||
| 	// we first remove the path prefix if there is one. | ||||
| 	if lastslash := strings.LastIndex(name, "/"); lastslash >= 0 { | ||||
| 		pkg += name[:lastslash] + "/" | ||||
| 		name = name[lastslash+1:] | ||||
| 	} | ||||
| 	if period := strings.Index(name, "."); period >= 0 { | ||||
| 		pkg += name[:period] | ||||
| 		name = name[period+1:] | ||||
| 	} | ||||
|  | ||||
| 	name = strings.Replace(name, "·", ".", -1) | ||||
| 	return pkg, name | ||||
| } | ||||
		Reference in New Issue
	
	Block a user