Slitter is a C- and Rust-callable slab allocator implemented primarily in Rust, with some C for performance or to avoid unstable Rust features.

Overview

Slitter is a less footgunny slab allocator

Build Status

Slitter is a classically structured thread-caching slab allocator that's meant to help write reliable long-running programs.

Given this goal, Slitter does not prioritise speed. The primary goal is instead to help applications handle inevitable memory management errors--be it with built-in statistics, with runtime detection, or by controlling their blast radius--while keeping the allocator's performance competitive with the state of the art. The other important goal is to let applications customise how Slitter requests memory from the operating system.

See doc/fast_path.md for details on allocation performance. For the rest of the allocator at a high level, refer to doc/design.md. Due to the type-stability guarantee, external fragmentation is essentially out of scope, and the slab/bump pointer allocation scheme keeps internal fragmentation to a very low level (only for metadata and guard pages, on the order of 2-3%, more once we add internal guard pages).

Current guarantees:

  1. Slitter will detect mismatching classes when recycling allocations, and will often also crash when it receives an address that it does not manage. Without this guarantee, it's too easy for heap usage statistics to become useless, and for incorrectly paired release calls to turn into memory corruption, far from the erroneous call.

  2. Slitter does not have any in-band metadata. This means no metadata next to the application's allocations, ripe for buffer overflows (we maintain guard pages between data and metadata), and also no intrusive linked list that would be vulnerable to use-after-free.

  3. Slitter-allocated data has a stable type: once an address has been returned to the mutator for a given allocation class, that address will always be valid, and will always be used for data of that class. Per #2, Slitter does not use intrusive linked lists, so the data reflects what the application stored there, even once it has been recycled. This lets application code rely on benign use-after-free in non-blocking algorithms instead of, e.g., SMR. The guarantee also means that any double-free or malign use-after-free will only affect the faulty allocation class.

Future guarantees:

  1. Slitter will detect when an interior pointer is freed.

  2. Slitter will detect most buffer overflows that cross allocation classes, with guard pages.

  3. Slitter will always detect frees of addresses it does not manage.

  4. Slitter will detect most back-to-back double-frees.

Future features:

a. Slitter will let each allocation class determine how its backing memory should be allocated (e.g., cold data could live in a file-backed mapping for opt-in swapping).

b. Slitter will track the number of objects allocated and recycled in each allocation class.

c. Slitter will sample a small fraction of allocations for heap profiling.

How to use Slitter as a C library

In order to use Slitter as a C library, we must first build a static library with Cargo. Slitter can only be called from C via static linkage because Cargo will otherwise hide our C functions. However, this also exposes internal Rust symbols, so there can only be one statically linked Rust library in any executable.

See examples/demo.c for a sample integration, which also demonstrates some of the additional checks unlocked by explicit allocation class tags. Execute that file in sh (i.e., sh examples/demo.c) to build Slitter, build demo.c and link it against Slitter, and run the resulting demo executable.

The #ifdef MISMATCH section allocates an object of a derived struct type, and releases it as the base type. The base field is the first member of the derived struct, so a plain malloc/free interface is unable to tell the difference. However, since the caller must tell slitter_release what allocation class it expects the freed pointer to be in, Slitter can detect the mismatch.

How to use Slitter within a Rust uber-crate

When linking multiple Rust libraries with other languages like C or C++, one must build a single statically linked (crate-type = ["staticlib"]) Rust crate that depends on all the Rust libraries we want to expose, and make sure to re-export the public extern "C" definitions from each of the dependencies.

How to use Slitter from Rust

We haven't explored that use case, except for tests. You can look at the unit tests at the bottom on src/class.rs. TL;DR: create new Class objects (they're copiable wrappers around NonZeroU32), and call Class::allocate and Class::release.

Comments
  • README should mention how to integrate Slitter with existing project.

    README should mention how to integrate Slitter with existing project.

    How does one use Slitter? Can one simply connect it to a project like Jemalloc? If not, can there be some example project showing Slitter's strenglths (maybe with a separate deliberately buggy example that demonstrates that Slitter crashes controllably more often compared to other allocactors)?

    opened by vi 1
  • gdb macros to extract information about allocations

    gdb macros to extract information about allocations

    When debugging a core, it's useful to know what object class a pointer might be in, and the offset of any interior pointer from the beginning of the allocation. With a bit more work, we could even report the allocation status (active, recycled, not yet allocated...)?

    opened by pkhuong 0
  • Coverage-guided fuzz testing

    Coverage-guided fuzz testing

    We have some randomised testing with proptest, but we could probably exercise edge cases more reliably with branch coverage information. The main obstable is that allocation classes are immortal and stateful (they remember freed allocations), so we probably want to fork for each call... and rust fuzzers seem to really want to run in persistent mode.

    opened by pkhuong 0
  • Stop using the system allocator

    Stop using the system allocator

    People might want to use slitter in a no_std environment. There's no reason for slitter to need the system allocator: we already have access to memory mapping code, and we already manage freelists. Avoiding the system allocator altogether would also help us improve our isolation guarantees.

    opened by pkhuong 0
  • Per-allocation class statistics

    Per-allocation class statistics

    We can start with something simple: number of objects allocated in each class (it's easy enough to find out with the bump allocation index, coupled with a running sum of the runs that have already been exhausted).

    However, we will also want to know how many allocations are active (not in free magazines).

    We could keep a running count of the number of objects in the stack of freed magazines... maybe instead of the generation counter?

    Alternatively, we could instead track that in the thread-local state... if we make sure these states are immortal, a stats thread will be able to scan through all the thread's single-writer running counters.

    opened by pkhuong 0
  • Hook to sample allocation and release calls

    Hook to sample allocation and release calls

    We might want to see what call sites allocate objects that are never freed, once we have #6 . Once the bump allocation indexes are randomised (#5), should we just consistently sample calls that are at a few fixed offsets from the beginning of a chunk? Or should we store additional random numbers in the span metadata?

    opened by pkhuong 0
Owner
Backtrace Labs
Backtrace Labs
Sol is a lightweight language primarily designed for scripting environments

☀️ Sol A dynamically-typed (for now) and procedural programming language. About Sol is a lightweight language primarily designed for scripting environ

Joshua 3 Jul 25, 2022
Automatically generates Rust FFI bindings to C (and some C++) libraries.

bindgen bindgen automatically generates Rust FFI bindings to C (and some C++) libraries. For example, given the C header doggo.h: typedef struct Doggo

The Rust Programming Language 3.2k Jan 4, 2023
lens implemented in rust

Overview This project contains two crates: lens-rs and lens-rs_derive. The lens-rs provide some definitions of lens. The lens-rs_derive provide the ma

Danube 84 Dec 27, 2022
Python module implemented in Rust for counting the number of one bits in a numpy array.

bit-counter Package for counting the number of one bits in a numpy array of uint8 values. Implemented as a Python module using Rust, providing high pe

Andrew MacDonald 3 Jul 9, 2022
Robust and Fast tokenizations alignment library for Rust and Python

Robust and Fast tokenizations alignment library for Rust and Python Demo: demo Rust document: docs.rs Blog post: How to calculate the alignment betwee

Explosion 157 Dec 28, 2022
Rust Attribute-Based Encryption library rabe's C FFI binding , support CP-ABE and KP-ABE encrypt and decrypt, submodule of Rabe.Core c# library.

Rabe-ffi Rust Attribute-Based Encryption library rabe's C FFI binding , support CP-ABE and KP-ABE encrypt and decrypt, submodule of Rabe.Core c# libra

Aya0wind 2 Oct 10, 2022
Safe interop between Rust and C++

CXX — safe FFI between Rust and C++ This library provides a safe mechanism for calling C++ code from Rust and Rust code from C++, not subject to the m

David Tolnay 4.4k Jan 7, 2023
Bridge the gap between Haskell and Rust

Curryrs Curryrs (a play on the name of Haskell Curry, rs for Rust libraries, and it's pronunciation couriers) is a library for providing easy to use b

Michael Gattozzi 296 Oct 18, 2022
Rust bindings for writing safe and fast native Node.js modules.

Rust bindings for writing safe and fast native Node.js modules. Getting started Once you have the platform dependencies installed, getting started is

The Neon Project 7k Jan 4, 2023
Objective-C Runtime bindings and wrapper for Rust.

Objective-C Runtime bindings and wrapper for Rust. Documentation: http://ssheldon.github.io/rust-objc/objc/ Crate: https://crates.io/crates/objc Messa

Steven Sheldon 336 Jan 2, 2023
“The Tie Between Ruby and Rust.”

Rutie Rutie — /ro͞oˈˌtī/rOOˈˌtI/rüˈˌtaI/ Integrate Ruby with your Rust application. Or integrate Rust with your Ruby application. This project allows

Daniel P. Clark 726 Jan 2, 2023
A minimalist and safe ECS library for rust!

The full ECS (Entity-Component-System) library. Support an Open Source Developer! ♥️ Composed of two smaller libraries: world_dispatcher: the System p

Joël Lupien 124 Dec 19, 2022
A notebook app integrated with todo lists utility. Developed with Rust, WebAssembly, Yew and Trunk.

Flow.er A notebook app integrated with todo-list utility. Project flow.er is a Rust WASM app running in browser. Taking advantage of Yew and Trunk, it

null 45 Dec 31, 2022
A JavaScript Runtime built with Mozilla's SpiderMonkey Engine and Rust

Spiderfire Spiderfire is a javascript runtime built with Mozilla's SpiderMonkey engine and Rust. Spiderfire aims to disrupt the server-side javascript

Redfire 122 Dec 15, 2022
A rust library containing typings and utility functions dealing with the Public specification of the Internet Computer.

IC Types Contributing Please follow the guidelines in the CONTRIBUTING.md document. Goal This library contains typings and utility functions dealing w

DFINITY 5 Nov 28, 2022
Modern JavaScript runtime for Sony PSP, based on rust-psp and QuickJS.

PSP.js Modern JavaScript runtime for Sony PSP, based on rust-psp and QuickJS. ⚠️ Currently in PoC state, unusable for developing JavaScript apps yet.

Yifeng Wang 15 Nov 28, 2022
Implementation of the Radon and Inverse Radon Transforms in Rust

Radon Transform A rust and python implementation of the discretized version of the radon transform that I did out of boredom. The main mathematical tr

Atman Kar 0 Nov 8, 2021
🚀 Fast and 100% API compatible postcss replacer, built in Rust

postcss-rs ?? Fast and 100% API compatible postcss replacer, built in Rust ⚠️ DO NOT USE. STILL WORK IN PROGRESS. Performance Improvement Tokenize boo

null 472 Dec 28, 2022
A simple programming language made for scripting inspired on rust and javascript.

FnXY Programming Language Quick move: CONTRIBUTING | LICENSE What? FnXY is a simple programming language made for scripting inspired on rust and javas

null 2 Nov 27, 2021