stack

package
v1.0.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 29, 2017 License: Apache-2.0 Imports: 21 Imported by: 0

Documentation

Overview

Package stack analyzes stack dump of Go processes and simplifies it.

It is mostly useful on servers will large number of identical goroutines, making the crash dump harder to read than strictly necesary.

Example
in := bytes.NewBufferString(crash)
goroutines, err := ParseDump(in, os.Stdout)
if err != nil {
	return
}

// Optional: Check for GOTRACEBACK being set, in particular if there is only
// one goroutine returned.

// Use a color palette based on ANSI code.
p := &Palette{}
buckets := SortBuckets(Bucketize(goroutines, AnyValue))
srcLen, pkgLen := CalcLengths(buckets, false)
for _, bucket := range buckets {
	io.WriteString(os.Stdout, p.BucketHeader(&bucket, false, len(buckets) > 1))
	io.WriteString(os.Stdout, p.StackLines(&bucket.Signature, srcLen, pkgLen, false))
}
Output:

panic: oh no!

1: running
         panic.go:464 panic(0, 0)
    main foo.go:45    crash2(0x7fe50b49d028, 0xc82000a1e0)
    main foo.go:50    main()

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Augment

func Augment(goroutines []Goroutine)

Augment processes source files to improve calls to be more descriptive.

It modifies goroutines in place.

func Bucketize

func Bucketize(goroutines []Goroutine, similar Similarity) map[*Signature][]Goroutine

Bucketize returns the number of similar goroutines.

func CalcLengths

func CalcLengths(buckets Buckets, fullPath bool) (int, int)

CalcLengths returns the maximum length of the source lines and package names.

Types

type Arg

type Arg struct {
	Value uint64 // Value is the raw value as found in the stack trace
	Name  string // Name is a pseudo name given to the argument
}

Arg is an argument on a Call.

func (*Arg) IsPtr

func (a *Arg) IsPtr() bool

IsPtr returns true if we guess it's a pointer. It's only a guess, it can be easily be confused by a bitmask.

func (Arg) String

func (a Arg) String() string

type Args

type Args struct {
	Values    []Arg    // Values is the arguments as shown on the stack trace. They are mangled via simplification.
	Processed []string // Processed is the arguments generated from processing the source files. It can have a length lower than Values.
	Elided    bool     // If set, it means there was a trailing ", ..."
}

Args is a series of function call arguments.

func (*Args) Equal

func (a *Args) Equal(r *Args) bool

Equal returns true only if both arguments are exactly equal.

func (*Args) Merge

func (a *Args) Merge(r *Args) Args

Merge merges two similar Args, zapping out differences.

func (*Args) Similar

func (a *Args) Similar(r *Args, similar Similarity) bool

Similar returns true if the two Args are equal or almost but not quite equal.

func (Args) String

func (a Args) String() string

type Bucket

type Bucket struct {
	Signature
	Routines []Goroutine
}

Bucket is a stack trace signature and the list of goroutines that fits this signature.

func (*Bucket) First

func (b *Bucket) First() bool

First returns true if it contains the first goroutine, e.g. the ones that likely generated the panic() call, if any.

func (*Bucket) Less

func (b *Bucket) Less(r *Bucket) bool

Less does reverse sort.

type Buckets

type Buckets []Bucket

Buckets is a list of Bucket sorted by repeation count.

func SortBuckets

func SortBuckets(buckets map[*Signature][]Goroutine) Buckets

SortBuckets creates a list of Bucket from each goroutine stack trace count.

func (Buckets) Len

func (b Buckets) Len() int

func (Buckets) Less

func (b Buckets) Less(i, j int) bool

func (Buckets) Swap

func (b Buckets) Swap(i, j int)

type Call

type Call struct {
	SourcePath string   // Full path name of the source file
	Line       int      // Line number
	Func       Function // Fully qualified function name (encoded).
	Args       Args     // Call arguments
}

Call is an item in the stack trace.

func (*Call) Equal

func (c *Call) Equal(r *Call) bool

Equal returns true only if both calls are exactly equal.

func (*Call) FullSourceLine

func (c *Call) FullSourceLine() string

FullSourceLine returns "/path/to/source.go:line".

func (*Call) IsPkgMain

func (c *Call) IsPkgMain() bool

IsPkgMain returns true if it is in the main package.

func (*Call) IsStdlib

func (c *Call) IsStdlib() bool

IsStdlib returns true if it is a Go standard library function. This includes the 'go test' generated main executable.

func (*Call) Merge

func (c *Call) Merge(r *Call) Call

Merge merges two similar Call, zapping out differences.

func (*Call) PkgSource

func (c *Call) PkgSource() string

PkgSource is one directory plus the file name of the source file.

func (*Call) Similar

func (c *Call) Similar(r *Call, similar Similarity) bool

Similar returns true if the two Call are equal or almost but not quite equal.

func (*Call) SourceLine

func (c *Call) SourceLine() string

SourceLine returns "source.go:line", including only the base file name.

func (*Call) SourceName

func (c *Call) SourceName() string

SourceName returns the base file name of the source file.

type Function

type Function struct {
	Raw string
}

Function is a function call.

Go stack traces print a mangled function call, this wrapper unmangle the string before printing and adds other filtering methods.

func (Function) IsExported

func (f Function) IsExported() bool

IsExported returns true if the function is exported.

func (Function) Name

func (f Function) Name() string

Name is the naked function name.

func (Function) PkgDotName

func (f Function) PkgDotName() string

PkgDotName returns "<package>.<func>" format.

func (Function) PkgName

func (f Function) PkgName() string

PkgName is the package name for this function reference.

func (Function) String

func (f Function) String() string

String is the fully qualified function name.

Sadly Go is a bit confused when the package name doesn't match the directory containing the source file and will use the directory name instead of the real package name.

type Goroutine

type Goroutine struct {
	Signature      // It's stack trace, internal bits, state, which call site created it, etc.
	ID        int  // Goroutine ID.
	First     bool // First is the goroutine first printed, normally the one that crashed.
}

Goroutine represents the state of one goroutine, including the stack trace.

func ParseDump

func ParseDump(r io.Reader, out io.Writer) ([]Goroutine, error)

ParseDump processes the output from runtime.Stack().

It supports piping from another command and assumes there is junk before the actual stack trace. The junk is streamed to out.

type Palette

type Palette struct {
	EOLReset string

	// Routine header.
	RoutineFirst string // The first routine printed.
	Routine      string // Following routines.
	CreatedBy    string

	// Call line.
	Package                string
	SourceFile             string
	FunctionStdLib         string
	FunctionStdLibExported string
	FunctionMain           string
	FunctionOther          string
	FunctionOtherExported  string
	Arguments              string
}

Palette defines the color used.

An empty object Palette{} can be used to disable coloring.

func (*Palette) BucketHeader

func (p *Palette) BucketHeader(bucket *Bucket, fullPath, multipleBuckets bool) string

BucketHeader prints the header of a goroutine signature.

func (*Palette) StackLines

func (p *Palette) StackLines(signature *Signature, srcLen, pkgLen int, fullPath bool) string

StackLines prints one complete stack trace, without the header.

type Signature

type Signature struct {
	// Use git grep 'gopark(|unlock)\(' to find them all plus everything listed
	// in runtime/traceback.go. Valid values includes:
	//     - chan send, chan receive, select
	//     - finalizer wait, mark wait (idle),
	//     - Concurrent GC wait, GC sweep wait, force gc (idle)
	//     - IO wait, panicwait
	//     - semacquire, semarelease
	//     - sleep, timer goroutine (idle)
	//     - trace reader (blocked)
	// Stuck cases:
	//     - chan send (nil chan), chan receive (nil chan), select (no cases)
	// Runnable states:
	//    - idle, runnable, running, syscall, waiting, dead, enqueue, copystack,
	// Scan states:
	//    - scan, scanrunnable, scanrunning, scansyscall, scanwaiting, scandead,
	//      scanenqueue
	State     string
	CreatedBy Call // Which other goroutine which created this one.
	SleepMin  int  // Wait time in minutes, if applicable.
	SleepMax  int  // Wait time in minutes, if applicable.
	Stack     Stack
	Locked    bool // Locked to an OS thread.
}

Signature represents the signature of one or multiple goroutines.

It is effectively the stack trace plus the goroutine internal bits, like it's state, if it is thread locked, which call site created this goroutine, etc.

func (*Signature) Equal

func (s *Signature) Equal(r *Signature) bool

Equal returns true only if both signatures are exactly equal.

func (*Signature) Less

func (s *Signature) Less(r *Signature) bool

Less compares two Signature, where the ones that are less are more important, so they come up front. A Signature with more private functions is 'less' so it is at the top. Inversely, a Signature with only public functions is 'more' so it is at the bottom.

func (*Signature) Merge

func (s *Signature) Merge(r *Signature) *Signature

Merge merges two similar Signature, zapping out differences.

func (*Signature) Similar

func (s *Signature) Similar(r *Signature, similar Similarity) bool

Similar returns true if the two Signature are equal or almost but not quite equal.

type Similarity

type Similarity int

Similarity is the level at which two call lines arguments must match to be considered similar enough to coalesce them.

const (
	// ExactFlags requires same bits (e.g. Locked).
	ExactFlags Similarity = iota
	// ExactLines requests the exact same arguments on the call line.
	ExactLines
	// AnyPointer considers different pointers a similar call line.
	AnyPointer
	// AnyValue accepts any value as similar call line.
	AnyValue
)

type Stack

type Stack struct {
	Calls  []Call // Call stack. First is original function, last is leaf function.
	Elided bool   // Happens when there's >100 items in Stack, currently hardcoded in package runtime.
}

Stack is a call stack.

func (*Stack) Equal

func (s *Stack) Equal(r *Stack) bool

Equal returns true on if both call stacks are exactly equal.

func (*Stack) Less

func (s *Stack) Less(r *Stack) bool

Less compares two Stack, where the ones that are less are more important, so they come up front. A Stack with more private functions is 'less' so it is at the top. Inversely, a Stack with only public functions is 'more' so it is at the bottom.

func (*Stack) Merge

func (s *Stack) Merge(r *Stack) *Stack

Merge merges two similar Stack, zapping out differences.

func (*Stack) Similar

func (s *Stack) Similar(r *Stack, similar Similarity) bool

Similar returns true if the two Stack are equal or almost but not quite equal.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL