Skip to content

Define what #[global_allocator] *really* means #25

Open
@ckaran

Description

@ckaran

Summary

I want to create a new crate that can be used as a global allocator, but I don't want anything within my crate using my own allocator, nor do I want anything that my crate is depending on to rely on my allocator.

Background

I'm sketching out the design for a new crate that will help analyze other crate's allocation behavior, kind of like valgrind, but for places where valgrind doesn't work. My plan is to use backtrace, counter, and dipstick within my allocator crate. So far, so good, since my allocator is only for instrumentation, I can just use the system allocator as my global allocator, and everything works as expected.

The problem comes in when someone else wants to use my crate to instrument their own code. Per the documentation for the #[global_allocator] attribute:

This attribute allows configuring the choice of global allocator. You can use this to implement a completely custom global allocator to route all default allocation requests to a custom object.

and

The #[global_allocator] can only be used once in a crate or its recursive dependencies.

At this point, I'm kind of stuck; I can't define #[global_allocator] in my own crate, as that would prevent end users from using it. When end users define it so that they can use my crate, they will force my crate to use itself in the allocation process, which could lead to recursive headaches.

Potential solutions

New attributes

Create a new attribute (#[local_allocator]?) that overrides the setting for the global allocator that gets applied to a crate and its recursive dependencies.

The main issue with this is the intersection of the crates that both my instrumentation crate and the user crate need to use; in that case, we need to either have two independent copies of the same code, or have some way of distinguishing which allocator to use when.

Binary-only distribution

Compile my instrumentation crate separately (and statically) from the user crate, forcing them to link in the binary.

This may be the best solution right now, but it may cause unforeseen toolchain issues (e.g., did the user remember to compile in debug symbols for both the user crate and my separately compiled crate?). In short, it doesn't feel very ergonomic.

Other, better solutions?

I feel like that there should be a better way than these solutions which don't break any guarantees that rust is currently providing. However, I can't think of any. Thoughts/ideas anyone?

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions