The Go runtime scheduler's clever way of dealing with system calls
> One of Go’s signature features is goroutines, which are lightweight threads that are managed by the Go runtime. The Go runtime implements goroutines using a M:N work stealing scheduler to multiplex goroutines on to operating system threads. The scheduler has special terminology for three important entities; a G is a goroutine, an M is an OS thread (a ‘machine’), and a P is a ‘processor’, which at its core is a limited resource that must be claimed by an M in order to run Go code. Having a limited supply of Ps is how Go limits how many things it will do at once, so as to not overload the overall system; generally there is one P per actual CPU that the OS reports (the number of Ps is GOMAXPROCS).
Non-blocking I/O in Go
> Whether you know it or not, if you are using Go you are probably using non-blocking I/O. This post will dig in a little into that, but go further into how you can actually take more control of the I/O handling in Go. This is especially nice as go1.11 and go1.12 add some very interesting interfaces to help with this.
Go memory ballast: How I learnt to stop worrying and love the heap
> The heap size is the total size of allocations on the heap. Therefore, if a ballast of 10 GiB is allocated, the next GC will only trigger when the heap size grows to 20 GiB. At that point, there will be roughly 10 GiB of ballast + 10 GiB of other allocations.
Gomium pwn challenge
> By doing the above we create a race where we access the implementation of X with the context of good that means if we “win” then inside the unsafe implementation f from the bad context will be used as a function pointer instead of a pointer to an integer. This will result in calling an arbitrary address (0x1337 in our case) which sounds quite promising.
Exploiting torn reads for fun and profit.
Security assessment techniques for Go projects
> With a better understanding of the root causes, we searched for existing tooling to help us quickly and effectively instrument client codebases. The result was a sample of static and dynamic open-source tools, including several that were Go-agnostic. To complement these tools, we also identified several compiler configurations that help with instrumentation.
Useful for developers who aren’t auditors as well.
Function Currying in Go
> Go can be used to program in a functional style, previously I’ve written about how we can use this to implement Continuation Passing Style programming. As such, it is possible to implement currying in Go as well. Before we take a look at how we can implement this in Go, let’s take a practical look at what function currying actually is, and why we want this.
Introducing Ristretto: A High-Performance Go Cache
> With over six months of research and development, we’re proud to announce the initial release of Ristretto: A High Performance, Concurrent, Memory-Bound Go cache. It is contention-proof, scales well and provides consistently high hit-ratios.
Interesting read even if only for the links to prior art and research.
Go 1.13 Release Notes
> The latest Go release, version 1.13, arrives six months after Go 1.12. Most of its changes are in the implementation of the toolchain, runtime, and libraries.
Octal numbers (0o747) though old syntax remains, 123_456 separators, TLS 1.3.
Go Module Mirror and Checksum Database Launched
> We are excited to share that our module mirror, index, and checksum database are now production ready! The go command will use the module mirror and checksum database by default for Go 1.13 module users.
Go compiler intrinsics
> Over the years there have been various proposals for an inline assembly syntax similar to gcc’s asm(...) directive. None have been accepted by the Go team. Instead, Go has added intrinsic functions1.
> An intrinsic function is Go code written in regular Go. These functions are known the the Go compiler which contains replacements which it can substitute during compilation.
Yaegi is Another Elegant Go Interpreter
> Despite being static and strongly typed, Go feels like a dynamic language. The standard library even provides the Go parser used by the compiler and the reflection system to interact dynamically with the runtime. So why not just take the last logical step and finally build a complete Go interpreter?
> Programming languages for high level scripting and for low level implementation are usually different. This time, with Go, we have an opportunity to unify both. Imagine all the C/C++/Java fast libraries for Python being written in Python instead. That’s what Yaegi is for Go (or, the reverse). No burden due to syntax switch, no need to rewrite or modify slow code to make it fast, and full access to goroutines, channels, type safety, etc. at script level.
Efficient Go APIs with the mid-stack inliner
> A common task in Go API design is returning a byte slice. In this post I will explore some old techniques and a new one.
Go compiler internals: adding a new statement to Go
> This is the first post in a two-part series that takes a tutorial-based approach to exploring the Go compiler. The compiler is large and would require a small book to describe properly, so the idea of these posts is to provide a quick depth-first dive instead. I plan to write more descriptive posts on specific areas of the compiler in the future.
Understanding real-world concurrency bugs in Go
> We perform the first systematic study on concurrency bugs in real Go programs. We studied six popular Go software [projects] including Docker, Kubernetes, and gRPC. We analyzed 171 concurrency bugs in total, with more than half of them caused by non-traditional, Go-specific problems. Apart from root causes of these bugs, we also studied their fixes, performed experiments to reproduce them, and evaluated them with two publicly-available Go bug detectors.
Go has no type for types in the language
> Part of what this means is that in Go, you cannot write an expression like ‘x := y.(type)’ not just because the language syntax forbids it, but because there is no standard type that the variable x can be. If you wanted to allow this, you would have to create a new Go type and define what its behavior was.
Can two new objects point to the same memory address in GoLang?
> This is because the memory allocation on heap calls the newobject function in runtime package. newobject function would invoke mallocgc function to allocate memory. This function is a bit special and it has some logic to check whether an object is indeed occupying memory or not, if no memory is needed, the address of zerobase(a global variable) will be assigned to it. In the above example snippet, both a and c are empty struct which doesn’t need memory. Hence both a and c are having the same memory address which is the address of zerobase.
Representative Line: Log Every Error
> This code knows that accessing the logger object is code that can throw an error, so if it gets an error fetching the logger object it… logs the error. With the logger object that returned some kind of error.
Recursive failure is best failure.
Go Concurrency from the Ground Up
> Sometimes the best way to learn something is to build it. This guide will walk you through how to reproduce Go’s concurrency features in another programming language.
goroutine stack growth latency
> Instead of using tokens to limit the number of goroutines that can be spawned, we spawn all the goroutines upfront and then use the channel to assign them work. This still limits the concurrency to the specified limit, but prevents us from having to allocate new goroutine stacks over and over again.
Using dynamic libraries in static Go binaries
> Do keep in mind, this directive is purposely not part of the language specification. It should probably only be done in Go’s runtime package.