Skip to content

Vec allocation #[track_caller] should be removed #146963

Closed

Description

@Noratrieb

#126557 added #[track_caller] to lots of allocating methods on Vec.

The description of all 3 PRs are very light on details, and what they don't reveal (and their added tests can't reveal since there are none):

  1. This doesn't work by default, as OOM currently isn't surfaced as a panic. The OOM messages have no location whatsoever.
  2. Even with -Zoom=panic, it doesn't work today, locations always point at the alloc crate.

I am a bit puzzled about 1). Was this never tested when the PR was opened or am I missing something? For 2) I didn't verify whether it worked originally, but even if it did, it then broke later. No one bothered to report its breakage, which I take as evidence that this feature is not very useful (probably due to 1)).

I don't think this feature is that useful because while it can be neat to see the location immediately, it's not that useful since backtraces do the same thing with only slightly more effort. If it was free I wouldn't mind, but it is not:

The feature had a 1-2% binary size impact, which is pretty significant (which was pointed out by @nnethercote on the PR). It meant that every inclined .push() had to get a location before calling the grow function, which is several instructions.

Test code:

Vec::<u32>::with_capacity(100000000000000);
struct CookedAlloc;

unsafe impl std::alloc::GlobalAlloc for CookedAlloc {
  unsafe fn alloc(&self, layout: std::alloc::Layout) -> *mut u8 {
    if layout.size() > 1_0000 {
      std::ptr::null_mut()
    } else {
      std::alloc::System.alloc(layout)
    }
  }

  unsafe fn dealloc(&self,ptr: *mut u8,layout: std::alloc::Layout) {}
}

#[global_allocator]
static GALLOC: CookedAlloc = CookedAlloc;

fn main() {
  let mut v = Vec::new();

  for i in 0.. {
    v.push([0; 1_000_000]);
  }
}

Example output (default):

memory allocation of 400000000000000 bytes failed

Example output (from push, -Zoom=panic):

thread 'main' panicked at library/std/src/alloc.rs:356:9:
memory allocation of 4000000 bytes failed
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

Activity

  1. added
    needs-triageThis issue may need triage. Remove when done. See docs forge.rust-lang.org/release/issue-triaging
    on Sep 24, 2025
  2. Noratrieb commented on Sep 24, 2025

    @Noratrieb
    MemberAuthor

    @GrigorenkoPV @nvzqz @joshtriplett since you were involved there, maybe you know something I forgot

  3. added
    C-bugCategory: This is a bug.
    I-heavyIssue: Problems and improvements with respect to binary size of generated code.
    T-libsRelevant to the library team, which will review and decide on the PR/issue.
    and removed
    needs-triageThis issue may need triage. Remove when done. See docs forge.rust-lang.org/release/issue-triaging
    on Sep 24, 2025
  4. Noratrieb commented on Sep 24, 2025

    @Noratrieb
    MemberAuthor

    Here's example Assembly that shows the overhead:

    See lea rsi, [rip + .Lanon.e3e90fd6d2a7c4661a1a3acf2f60bc6d.1] and the associated static allocation.

    pub fn cook(v: &mut Vec<u8>, b: u8) {
      v.push(b);
    }
    cook:
            push    rbp
            push    r14
            push    rbx
            mov     ebp, esi
            mov     rbx, rdi
            mov     r14, qword ptr [rdi + 16]
            cmp     r14, qword ptr [rdi]
            jne     .LBB0_2
            lea     rsi, [rip + .Lanon.e3e90fd6d2a7c4661a1a3acf2f60bc6d.1]
            mov     rdi, rbx
            call    qword ptr [rip + alloc::raw_vec::RawVec<T,A>::grow_one@GOTPCREL]
    .LBB0_2:
            mov     rax, qword ptr [rbx + 8]
            mov     byte ptr [rax + r14], bpl
            inc     r14
            mov     qword ptr [rbx + 16], r14
            pop     rbx
            pop     r14
            pop     rbp
            ret
    
    .Lanon.e3e90fd6d2a7c4661a1a3acf2f60bc6d.0:
            .asciz  "/app/example.rs"
    
    .Lanon.e3e90fd6d2a7c4661a1a3acf2f60bc6d.1:
            .quad   .Lanon.e3e90fd6d2a7c4661a1a3acf2f60bc6d.0
            .asciz  "\017\000\000\000\000\000\000\000\002\000\000\000\005\000\000"
    
  5. nnethercote commented on Sep 24, 2025

    @nnethercote
    Contributor

    Vec methods like push are incredibly hot.

  6. GrigorenkoPV commented on Sep 24, 2025

    @GrigorenkoPV
    Contributor

    I am fine with this being reverted. I only picked this up because I saw the PR die 3 times not based on merit, but simply due to merge conflicts.

    So if the value is not really there, it makes sense to revert.

  7. added a commit that references this issue on Sep 28, 2025
    c7f6aa2
  8. added 2 commits that reference this issue on Sep 29, 2025
    6876493
    f0be568
  9. added a commit that references this issue on Oct 9, 2025
    2015731
  10. added a commit that references this issue on Oct 18, 2025
    4f868ca
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: This is a bug.I-heavyIssue: Problems and improvements with respect to binary size of generated code.T-libsRelevant to the library team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions