1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677 |
- // Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
- //
- // This Source Code Form is subject to the terms of the MIT License.
- // If a copy of the MIT was not distributed with this file,
- // You can obtain one at https://github.com/gogf/gf.
- package gdebug
- import (
- "bytes"
- "fmt"
- "runtime"
- )
- // PrintStack prints to standard error the stack trace returned by runtime.Stack.
- func PrintStack(skip ...int) {
- fmt.Print(Stack(skip...))
- }
- // Stack returns a formatted stack trace of the goroutine that calls it.
- // It calls runtime.Stack with a large enough buffer to capture the entire trace.
- func Stack(skip ...int) string {
- return StackWithFilter(nil, skip...)
- }
- // StackWithFilter returns a formatted stack trace of the goroutine that calls it.
- // It calls runtime.Stack with a large enough buffer to capture the entire trace.
- //
- // The parameter `filter` is used to filter the path of the caller.
- func StackWithFilter(filters []string, skip ...int) string {
- return StackWithFilters(filters, skip...)
- }
- // StackWithFilters returns a formatted stack trace of the goroutine that calls it.
- // It calls runtime.Stack with a large enough buffer to capture the entire trace.
- //
- // The parameter `filters` is a slice of strings, which are used to filter the path of the
- // caller.
- //
- // TODO Improve the performance using debug.Stack.
- func StackWithFilters(filters []string, skip ...int) string {
- number := 0
- if len(skip) > 0 {
- number = skip[0]
- }
- var (
- name = ""
- space = " "
- index = 1
- buffer = bytes.NewBuffer(nil)
- ok = true
- pc, file, line, start = callerFromIndex(filters)
- )
- for i := start + number; i < maxCallerDepth; i++ {
- if i != start {
- pc, file, line, ok = runtime.Caller(i)
- }
- if ok {
- if filterFileByFilters(file, filters) {
- continue
- }
- if fn := runtime.FuncForPC(pc); fn == nil {
- name = "unknown"
- } else {
- name = fn.Name()
- }
- if index > 9 {
- space = " "
- }
- buffer.WriteString(fmt.Sprintf("%d.%s%s\n %s:%d\n", index, space, name, file, line))
- index++
- } else {
- break
- }
- }
- return buffer.String()
- }
|