Giter Club home page Giter Club logo

gotcha's Introduction

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.

gotcha's People

Contributors

1pkg avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

gotcha's Issues

fatal error: unexpected signal during runtime execution

Run the following code

	n := 3
	for i := 0; i < n; i++ {
		go func() {
			size := rand.Intn(100)
			innerSlice := make([]string, size, size)
			for _, v := range innerSlice {
				_ = v
			}

			gotcha.Trace(context.Background(), func(ctx gotcha.Context) {
				b, o, c := ctx.Used()
				fmt.Println("allocation info ", b, o, c)
			})
			time.Sleep(time.Duration(30) * time.Second)

		}()

	}

under centos with golang 1.16, error fatal error: unexpected signal during runtime execution comes up. Is there anything missing?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.