Skip to content

Commit

Permalink
Update parser to understand function names
Browse files Browse the repository at this point in the history
  • Loading branch information
thomshutt committed Apr 4, 2023
1 parent 383b130 commit bd1f0a0
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 13 deletions.
33 changes: 21 additions & 12 deletions internal/stack/stacks.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@ const _defaultBufferSize = 64 * 1024 // 64 KiB

// Stack represents a single Goroutine's stack.
type Stack struct {
id int
state string
firstFunction string
fullStack *bytes.Buffer
id int
state string
functions []string
fullStack *bytes.Buffer
}

// ID returns the goroutine ID.
Expand All @@ -57,13 +57,21 @@ func (s Stack) Full() string {

// FirstFunction returns the name of the first function on the stack.
func (s Stack) FirstFunction() string {
return s.firstFunction
if len(s.functions) > 0 {
return s.functions[0]
}
return ""
}

// AllFunctions returns the names of all functions on the stack.
func (s Stack) AllFunctions() []string {
return s.functions
}

func (s Stack) String() string {
return fmt.Sprintf(
"Goroutine %v in state %v, with %v on top of the stack:\n%s",
s.id, s.state, s.firstFunction, s.Full())
s.id, s.state, s.FirstFunction(), s.Full())
}

func getStacks(all bool) []Stack {
Expand All @@ -82,7 +90,6 @@ func getStacks(all bool) []Stack {
}

// If we see the goroutine header, start a new stack.
isFirstLine := false
if strings.HasPrefix(line, "goroutine ") {
// flush any previous stack
if curStack != nil {
Expand All @@ -94,11 +101,10 @@ func getStacks(all bool) []Stack {
state: goState,
fullStack: &bytes.Buffer{},
}
isFirstLine = true
}
curStack.fullStack.WriteString(line)
if !isFirstLine && curStack.firstFunction == "" {
curStack.firstFunction = parseFirstFunc(line)
if f := parseFunc(line); f != "" {
curStack.functions = append(curStack.functions, f)
}
}

Expand Down Expand Up @@ -127,12 +133,15 @@ func getStackBuffer(all bool) []byte {
}
}

func parseFirstFunc(line string) string {
func parseFunc(line string) string {
line = strings.TrimSpace(line)
if idx := strings.LastIndex(line, "("); idx > 0 {
return line[:idx]
}
panic(fmt.Sprintf("function calls missing parents: %q", line))
if idx := strings.LastIndex(line, "created by"); idx >= 0 {
return strings.TrimPrefix(line, "created by ")
}
return ""
}

// parseGoStackHeader parses a stack header that looks like:
Expand Down
7 changes: 6 additions & 1 deletion options.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,12 @@ func Cleanup(cleanupFunc func(exitCode int)) Option {
// e.g., go.uber.org/goleak.IgnoreTopFunction
func IgnoreAnyFunction(f string) Option {
return addFilter(func(s stack.Stack) bool {
return strings.Contains(s.Full(), f)
for _, f2 := range s.AllFunctions() {
if f == f2 {
return true
}
}
return false
})
}

Expand Down

0 comments on commit bd1f0a0

Please sign in to comment.