loc

package module
v0.5.1 Latest Latest
Warning

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

Go to latest
Published: Nov 11, 2023 License: MIT Imports: 9 Imported by: 0

README

Documentation Go workflow CircleCI codecov GolangCI Go Report Card GitHub tag (latest SemVer)

loc

It's a fast, alloc-free and convinient version of runtime.Caller.

Performance benefits are available when using the nikandfor_loc_unsafe build tag. This relies on the internal runtime implementation, which means that older versions of the package may not compile with future versions of Go. Without the tag, it is safe to use with any version of Go.

It was born from tlog.

What is similar

Caller

pc := loc.Caller(1)
ok := pc != 0
name, file, line := pc.NameFileLine()
e := pc.FuncEntry()

// is similar to

pc, file, line, ok := runtime.Caller(1) 
f := runtime.FuncForPC(pc)
name := f.Name()
e := f.Entry()

Callers

pcs := loc.Callers(1, 3)
// or
var pcsbuf [3]loc.PC
pcs := loc.CallersFill(1, pcsbuf[:])

for _, pc := range pcs {
    name, file, file := pc.NameFileLine()
}

// is similar to
var pcbuf [3]uintptr
n := runtime.Callers(2, pcbuf[:])

frames := runtime.CallersFrames(pcbuf[:n])
for {
    frame, more := frames.Next()
    
    _, _, _ = frame.Function, frame.File, frame.Line

    if !more {
        break
    }
}

What is different

Normalized path

loc returns cropped filepath.

github.com/nikandfor/loc/func_test.go

# vs

/home/nik/nikandfor/loc/github.com/nikandfor/loc/func_test.go
Performance

In loc the full cycle (get pc than name, file and line) takes 360=200+160 (200+0 when you repeat) ns whereas runtime takes 690 (640 without func name) + 2 allocs per each frame.

It's up to 3.5x improve.

BenchmarkLocationCaller-8              	 5844801	       201.8 ns/op	       0 B/op	       0 allocs/op
BenchmarkLocationNameFileLine-8        	 7313388	       156.5 ns/op	       0 B/op	       0 allocs/op
BenchmarkRuntimeCallerNameFileLine-8   	 1709940	       689.1 ns/op	     216 B/op	       2 allocs/op
BenchmarkRuntimeCallerFileLine-8       	 1917613	       642.1 ns/op	     216 B/op	       2 allocs/op

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Cached

func Cached(l PC) (ok bool)

func SetCache

func SetCache(l PC, name, file string, line int)

SetCache sets name, file and line for the PC. It allows to work with PC in another binary the same as in original.

func SetCacheBytes added in v0.4.0

func SetCacheBytes(l PC, name, file []byte, line int)

Types

type PC

type PC uintptr

PC is a program counter alias. Function name, file name and line can be obtained from it but only in the same binary where Caller or FuncEntry was called.

func Caller

func Caller(s int) (r PC)

Caller returns information about the calling goroutine's stack. The argument s is the number of frames to ascend, with 0 identifying the caller of Caller.

It's hacked version of runtime.Caller with no allocs.

func CallerOnce

func CallerOnce(s int, pc *PC) (r PC)

func FuncEntry added in v0.5.0

func FuncEntry(s int) (r PC)

FuncEntry returns information about the calling goroutine's stack. The argument s is the number of frames to ascend, with 0 identifying the caller of Caller.

It's hacked version of runtime.Callers -> runtime.CallersFrames -> Frames.Next -> Frame.Entry with no allocs.

func FuncEntryFromFunc added in v0.5.0

func FuncEntryFromFunc(f interface{}) PC

func FuncEntryOnce added in v0.5.0

func FuncEntryOnce(s int, pc *PC) (r PC)

func (PC) Format

func (l PC) Format(s fmt.State, c rune)

Format is fmt.Formatter interface implementation.

func (PC) FuncEntry

func (l PC) FuncEntry() PC

func (PC) NameFileLine

func (l PC) NameFileLine() (name, file string, line int)

NameFileLine returns function name, file and line number for location.

This works only in the same binary where location was captured.

This functions is a little bit modified version of runtime.(*Frames).Next().

func (PC) String

func (l PC) String() string

String formats PC as base_name.go:line.

Works only in the same binary where Caller of FuncEntry was called. Or if PC.SetCache was called.

type PCs

type PCs []PC

PCs is a stack trace. It's quiet the same as runtime.CallerFrames but more efficient.

func Callers

func Callers(skip, n int) PCs

Callers returns callers stack trace.

It's hacked version of runtime.Callers -> runtime.CallersFrames -> Frames.Next -> Frame.Entry with only one alloc (resulting slice).

func CallersFill

func CallersFill(skip int, tr PCs) PCs

CallersFill puts callers stack trace into provided slice.

It's hacked version of runtime.Callers -> runtime.CallersFrames -> Frames.Next -> Frame.Entry with no allocs.

func (PCs) Format

func (t PCs) Format(s fmt.State, c rune)

func (PCs) FormatString

func (t PCs) FormatString(flags string) string

FormatString formats PCs as list of type_name (file.go:line)

Works only in the same binary where Caller of FuncEntry was called. Or if PC.SetCache was called.

func (PCs) String

func (t PCs) String() string

String formats PCs as list of type_name (file.go:line)

Works only in the same binary where Caller of FuncEntry was called. Or if PC.SetCache was called.

Jump to

Keyboard shortcuts

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