Backtrace Engineering
engineering.backtrace.io · Company blog · on HN since 2019
Backtrace's engineering blog covers systems work such as hash functions, allocators, SQLite replication, and debugging tools.
What HN saysCommenters find its Verneuil SQLite replication post interesting, and discuss its UMASH hash and its use of cross-modifying code for feature flags.
16HN people shared it
8linked it in comments
17stories submitted
211story points
2 years agolast shared
2019people per year2026
Most-shared posts
- 1UMASH: A fast and universal enough hash function7 people · 21 points · first shared 2020 · 4 comments on HN
- 2Verneuil: S3-backed asynchronous replication for SQLite4 people · 21 points · first shared 2021 · 8 comments on HN
- 3Fast Feature Flags3 people · 44 points · first shared 2021 · 3 comments on HN
- 4How hard is it to guide test case generators with branch coverage feedback?3 people · 6 points · first shared 2020 · discussion on HN
- 5Slitter: A slab allocator that trusts, but verifies2 people · 108 points · first shared 2021 · 31 comments on HN
- 6Our Workflows with Address Sanitizer and Valgrind2 people · 6 points · first shared 2019 · 2 comments on HN
- 7Stuff Your Logs2 people · 4 points · first shared 2021 · discussion on HN
- 8Triplefault: Djordje Todorovic on LLVM and debug information1 people · 1 points · first shared 2020 · discussion on HN
- 92020 03 11 how hard is it to guide test case generators with branch coverage feedback1 people · first shared 2022
What HN people wrote when they linked it
ahicks · 2024-11-05
Location: Seattle
Remote: Yes
Willing to relocate: No
Technologies: Rust, C/C++, Python, SQL, Kubernetes, many others
Résumé/CV: https://ahicks.io/files/resume.pdf
Email: [email protected]
My first resume-worthy project was working with Mozilla on the Rust compiler for 6 months [0], implementing the ability to reorder fields in structs to eliminate padding. My work here was primarily a cleanup project which also unblocked many other Rust layout features that people benefit from today. I then detoured into Python/Django on top of Kubernetes, writing scalable infrastructure such as a giant media transcoding cluster. After that, I pivoted back to C/C++ working at Backtrace I/O. If you play a lot of videogames, our software is probably on your system, as we indexed and processed native crashes for many of the largest videogame publishers. This was big data on the order of tens to hundreds of terabytes per day. I was able to attain exposure to the concerns at that scale--including custom database design. While there, I spearheaded the adoption of Rust in the org, initially for microservices and later as part of our C codebase. I'm now one of the most experienced Rust engineers you'll find. We did neat things some of which are open source, for example our feature flag system that rewrote code at runtime [1] and our Sqlite VFS that replicates to S3 [2]. As a benchmark of our success, we managed to be acquired by Sauce Labs, a company easily 10 times our…
thomasahle · 2023-06-07
> I think you're confusing proving that the hash function is collision resistant with the other goal which is hashing speed. If you really need a collision resistant hash you need to use a cryptographic hash function.
I wish this misconception would die. There is a great theory of algorithmic probabilistic hash functions, completely distinct from cryptographic hash functions. If you are designing a hash table, or a different algorithm using a hash function, you nearly always want the former kind.
The idea is that `Pr[h(x) = h(y)]` is small _no matter the inputs x and y_.
Here the probability is over the random seed of h.
Lots of good hash functions, like UMASH (https://engineering.backtrace.io/2020-08-24-umash-fast-enough-almost-u… has this guarantee.
Other fast hash functions, like MURMUR don't.
When a function doesn't have this guarantee, it means I can find sets of values x1, x2, ... that will likely collide under _any_ or most seeds!
Sure, if your inputs are basically random, this probably won't happen, but people can still use this to DDoS your hash table, or whatever you are coding.
Notice again, this has nothing to do with cryptography. It is all about probabilistic guarantees.
You can't just test the hash function on a fixed number of inputs and say it's good, since you may just have moved the "bad set" to somewhere else.
In this day and age there are super fast algorithmic hash functions with guaranteed low expected collisions. It's just…
stephen · 2022-02-15
I've wanted to use "SQLite db per user" for awhile now but haven't had the right problem domain for it yet. https://engineering.backtrace.io/2021-12-02-verneuil-s3-backed-asynchr… looks really interesting.
pkhuong · 2022-02-12
We've had a lot of success combining that approach (cffi instead of ctypes) with property-based testing (https://github.com/HypothesisWorks/hypothesis) for the query engine at backtrace: https://engineering.backtrace.io/2020-03-11-how-hard-is-it-to-guide-te… .
chubot · 2022-01-28
Surprisingly backtrace apparently uses self-modifying code in production for feature flags:
https://engineering.backtrace.io/2021-12-19-bounded-dynamicism-with-cr…
This is basically to make it zero cost (as far as I remember)
Google uses a similar system of feature flags, but as far as I know there's no self-modifying code. I guess Backtrace wants to put the flags in tight inner loops.
dtrace and I believe systemtap patch the executable at runtime, for similar performance reasons. But those are kernel features and not user applications.
sbahra · 2021-03-19
cstrahan · 2024-12-13
Note that you said “likely” and not “equally likely”. Therein lies your answer.
There are applications where hashes are used as identifiers, where it would be impossible to use the original data to resolve possible collisions. One example would be in RTTI (Run Time Type Information), when you want to check if two objects (of unknown-at-compile-time type) are instances of the same type. The only performant way to achieve this is if the compiler emits each type’s RTTI with a unique integer key to efficiently compare against, and this key must be unique across all object files and shared objects. In practice, this is done using hashing. If there is a collision, then the program behavior is undefined, so it is ideal to minimize probability of collision. You can see this issue in the Rust compiler project where there is ongoing discussion about how to handle this hashing, trying to balance compiler speed and collision likeliness:
https://github.com/rust-lang/rust/issues/129014
Another scenario would be like what Backtrace does: a hash is used to identify certain classes of errors in application code. The cost of analyzing each error is quite high (you have to load objects into memory, source maps (if available), perform symbolification, etc), so comparing any two errors every time you want to perform any metrics or retrieve associated data (like issue tracker identifiers) would reduce the performance to a point that any such application would be too slow to be useful. So a lot…
verdagon · 2023-06-24
This is one of the other three secret blends that I think could bring memory safety to C++!
I wrote a bit about using type-after-type as the basis for an entire language (Arrrlang, with a parrot mascot) in my last article [0] and a little bit in a post about memory safety for unsafe languages [1] which we eventually talked about at Handmade Seattle.
The downside is the extra memory usage, but I think we can combine it with temporary regions [2] to reduce it pretty drastically.
TIL the phrase type-after-type! I've also heard it referred to as type stability. [3] [4] If you squint, this is what we often do manually with Rust when the borrow checker influences us to use indices/IDs into central collections.
[0] https://verdagon.dev/blog/myth-zero-overhead-memory-safety
[1] https://verdagon.dev/blog/when-to-use-memory-safe-part-1#the-safer-way…
[2] https://verdagon.dev/blog/zero-cost-borrowing-regions-overview
[3] https://www.usenix.org/legacy/publications/library/proceedings/osdi96/…
[4] https://engineering.backtrace.io/2021-08-04-slitter-a-slab-allocator-t…