Skip to content

Latest commit

 

History

History
66 lines (49 loc) · 4.23 KB

README.MD

File metadata and controls

66 lines (49 loc) · 4.23 KB

Gotcha 🎯

lint test report version license godoc

go get -u github.com/1pkg/gotcha

blog post article

Introduction

Gotcha seamlessly patches go runtime to provide a convenient way to track amount of heap allocated bytes, objects, calls per goroutine.

package main

import (
	"context"
	"fmt"

	"github.com/1pkg/gotcha"
)

func main() {
	var v []int
	gotcha.Trace(context.Background(), func(ctx gotcha.Context) {
		v = make([]int, 100)
		b, o, c := ctx.Used() // bytes objects calls
		fmt.Println("initial allocation", b, o, c) // will print "initial allocation 824 101 2"
		gotcha.Trace(ctx, func(ctx gotcha.Context) {
			v = make([]int, 5000)
			b, o, c := ctx.Used() // bytes objects calls
			fmt.Println("derived allocation", b, o, c) // will print "derived allocation 40024 5001 2"
		})
		select {
		case <-ctx.Done():
			b, o, c := ctx.Used() // bytes objects calls
			fmt.Println("total allocations", b, o, c) // will print "total allocations 41840 5116 15"
		default:
			panic("unreachable")
		}
	}, gotcha.ContextWithLimitBytes(gotcha.KiB)) // set context allocation limit to one kilobit
	// note that prints above might be slightly different on your machine
	fmt.Println(len(v)) // 5000
}

Internals

Gotcha exposes function Track that tracks memory allocations for provided Tracer function. All traced allocations are attached to the single parameter of this tracer function Context object. Gotcha context fully implements context.Context interface and could be used to cancel execution if provided limits were exceeded. Gotcha supports nested tracing by providing gotcha context as the parent context for derived Tracer; then gotcha tracing context methods will also be targeting parent context as well as derived context.

Note that in order to work gotcha uses 1pkg/gomonkey based on bou.ke/monkey and 1pkg/golocal based on modern-go/gls packages to patch runtime mallocgc allocator entrypoint and trace per goroutine context limts. This makes gotcha inherits the same list of restrictions as modern-go/gls and bou.ke/monkey has.

It's important to know that gotcha is not trying to measure momentary memory usage which involves GC tracing into the act, keeping track on GC is rather a big task on it's own and out of scope for gotcha. Instead gotcha traces all memory allocated in monotonic increasing fashion where is only allocations are taken into consideration and all deallocations are discarded.

Note: despite that gotcha might work on your machine, it's super unsafe. It uses code assumption about mallocgc, depends on calling convention that could be changed, uses platform specific machine code direcly, etc. Alsp gotcha isn't expected to work on anything apart from amd64 with latest go runtime. So I highly discourage anyone to use gotcha in any production code or maybe even any code at all as it's extremely unsafe and not reliable and won't be supported in foreseeable future. Nevertheless, one could probably imagine reasonable use cases for this concept library in go benchmarks or test. Finally it's worth to say that primary intention to develop gotcha was learning and that gotcha doesn't have comprehensive tests coverage and support and not ready for any serious use case anyway

Licence

Gotcha is licensed under the MIT License.
See LICENSE for the full license text.