@prattmic that's a good one!
But it's difficult when writing libraries where it's more difficult to anticipate what people will do with them 🙈.
@prattmic that's a good one!
But it's difficult when writing libraries where it's more difficult to anticipate what people will do with them 🙈.
New Blog Post: 8 Unexpected Profiling Use Cases Beyond Performance Optimization
https://blog.felixge.de/8-unexpected-profiling-use-cases-beyond-performance-optimization/
I have released v0.1.0 of Gotraceui, the efficient frontend for Go execution traces. It is my latest project and an attempt at bringing Go's traces to the masses.
Please check it out at https://github.com/dominikh/gotraceui/releases/tag/v0.1.0
@javierhc yeah, gentraceback definitely accomplished a lot in its lifetime. More than most code, that's sure :).
@nemith hadn't seen sapling - looks cool!
Git: Yes, it's doable. But it still takes a lot of energy and discipline. But maybe years of just pushing more commits into PRs on GitHub have made me weak and lazy 🤣
@nemith yeah, GitHub PRs are a crime against humanity.
But even with Gerrit ... managing stacked patches seems hard. How do you go back to a patch early in the stack and refactor it when later patches depend on it? It seems very tedious to do the required rebase, conflict resolution, etc... ?
@klausman should land in 1.21 👍
💐RIP gentraceback
2010-03-23 - 2023-03-10
Thank you for all the unwinding.
So again, 👏🏻 to Austin Clements for this incredible work, but also
@prattmic for some fantastic review comments.
The people working on the Go runtime team are really incredible. ❤️
If you need a comparison (or laugh), feel free to look at my pathetic attempt from last year to do the same refactoring 🤣.
I spent a week on it and produced 54 chaotic patches that didn't even get me half way to a full iterator API.
I've still skipped over many other aspects, such as designing a nice API, dealing with inlining, etc. - but hopefully you can see why this is really gnarly stuff to be hacking on.
So now look at these 17 patches again. It's a real work of art 🙇🏻♂️.
Last but not least: Breaking up such a complex refactoring is necessary in order to give somebody a chance to review it.
And this makes everything harder. What if you're 10 patches in, and you notice a mistake in patch 3? It's possible, but very hard to make these kind of edits.
Next up are the build bots: Assuming you've got something work on your local machine, there is a decent chance you've broken things on another OS or architecture. You'll spend lots of time debugging these kind of failures.
Secondly you're not really writing Go. You're writing "runtime code" that has to be signal safe. The rules for this are incredibly subtle, and you'll quickly learn about write barriers and how the compiler will refuse to build things when you introduce them into this code.
Now let's explore why it's so difficult to refactor this function. The first reason is that it's insanely difficult to debug this code when you break it.
It'll produce the most cryptic panics, crashes, corruptions and issues you can imagine.
Speaking of arm64, it's part of why this function is complicated. ARM is a so called link architecture which works very different from intel when it comes to function calls.
A register, rather than the stack, is updated when CALLing a function. More here
Any bug in this function has a chance to break all Go applications.
If you're doubtful, look no further than some recent issue that caused Go programs on arm64 to become completely unresponsive due to gentraceback getting stuck in an infinite loop.
When I say load-bearing, I mean that without it, the GC won't be able to scan the stacks of your goroutines, and your goroutines won't be able to grow their stacks (which needs pointer adjustments).
It's an absolutely vital organ of the Go runtime.
To get why this is amazing engineering, first consider the old code.
gentraceback was a 500+ LoC monster function that will make you weep if you try to read it. And that's even before you realize how incredibly load-bearing it is.
https://github.com/golang/go/blob/go1.20.1/src/runtime/traceback.go#L24-L563
From a high level point of view, these patches are "just" a refactoring of the stack trace implementation in Go.
The gnarly old gentraceback() function has been replace with a new iterator API that is more flexible, yet easier to understand.