Skip to content

-Z extra-debug-info injects reference-count problem on @managed boxes #10609

@pnkfelix

Description

@pnkfelix

Caveat from the outset: The current ref-counting system will (or at least should) be replaced by a proper GC. I am fully aware of this, and I am fully aware that the test case below is making deliberate use of the ref-counting semantics.

Having said that... it still might be worth looking into this, since it might represent a bug in -Z extra-debug-info.

The bug is that the test below assert fails when compiled with -Z extra-debug-info:

% rustc a.rs && ./a
% rustc -Z extra-debug-info a.rs && ./a
warning: no debug symbols in executable (-arch x86_64)
task '<main>' failed at 'assertion failed: shared_count_at_outset == shared_count_at_finale', a.rs:29

The test (a.rs):

#[feature(managed_boxes)];
#[allow(unused_imports)];
use std::ptr;
use std::rt::local_heap;
use std::rt::local_heap::{MemoryRegion, Box};

fn sub(_prefix: &'static str, _x: ~Option<@int>) -> ~Option<@int> {
    debug!("{} x: {:?}", _prefix, _x);
    traverse_live_allocs();
    _x
}

fn subroutine_alloc() {
    #[allow(dead_assignment)];
    let mut x = ~None;
    x = sub("naughtyet", x);

    x = ~Some(@3);
    x = sub("allocated", x);

    *x = None;
    x = sub("overwrote", x);
}

fn main() {
    let shared_count_at_outset = traverse_live_allocs();
    subroutine_alloc();
    let shared_count_at_finale = traverse_live_allocs();
    assert!(shared_count_at_outset == shared_count_at_finale);
}

fn traverse_live_allocs() -> int {
    let bp : *mut Box = local_heap::live_allocs();
    debug!("bp: {:?}", bp);
    let mut cursor = bp;
    let mut count = 0;
    if cursor != ptr::mut_null() {
        loop {
            unsafe {
                debug!("{: >5d}: *cursor: \\{ ref_count: \
                         {}\n                  type_desc: \
                         {}\n                  prev: \
                         {}\n                  next: \
                         {}\n                  data: \
                         {:?}               \\}",
                         count,
                         (*cursor).ref_count,
                         (*cursor).type_desc,
                         (*cursor).prev,
                         (*cursor).next,
                         (*cursor).data );
                cursor = (*cursor).next;
            }
            count += 1;
            if cursor == ptr::mut_null() { break; }
            if cursor == bp { fail!("uh oh"); }
        }
    }
    count
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions