Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

segfault in repr with references #3501

Closed
erickt opened this issue Sep 15, 2012 · 5 comments
Closed

segfault in repr with references #3501

erickt opened this issue Sep 15, 2012 · 5 comments
Assignees
Labels
A-lifetimes Area: Lifetimes / regions A-type-system Area: Type system
Milestone

Comments

@erickt
Copy link
Contributor

erickt commented Sep 15, 2012

struct A {
    x: ~int,
    mut y: ~[&~int],
}

fn A() -> A {
    let a = A { x: ~1, y: ~[] };
    vec::push(a.y, &a.x);
    a
}

fn main() {
    let a = A();
    error!("%?", a);
}

Results in a secgault. The stack trace suggests it's in the repr function:

0x000000010007309d in repr::__extensions__::meth_10746::visit_self_describing_heap_alloc::_b764c3ece7f574bd::_04 ()
(gdb) bt
#0  0x000000010007309d in repr::__extensions__::meth_10746::visit_self_describing_heap_alloc::_b764c3ece7f574bd::_04 ()
#1  0x0000000000000000 in ?? ()
@nikomatsakis
Copy link
Contributor

This definitely should not type check. You are returning a pointer into the stack frame.

@ghost ghost assigned nikomatsakis Sep 15, 2012
@nikomatsakis
Copy link
Contributor

I added this to 0.4 milestone and assigned myself. I think it's pretty important to get this right. I'm having a hard time debugging it, though, due to #3506

@nikomatsakis
Copy link
Contributor

Actually, this is due to the unsound type of vec::push()! It's worse than I thought. If you change the example to:

struct A {
    x: ~int,
    mut y: ~[&~int],
}

fn push<T>(v: &mut ~[T], +x: T) {
    vec::push(*v, move x);
}

fn A() -> A {
    let a = A { x: ~1, y: ~[] };
    push(&mut a.y, &a.x);
    a
}

fn main() {
    let a = A();
    error!("%?", a);
}

then you get the region error I expected:

Running /usr/local/bin/rustc:
/Users/nmatsakis/tmp/bug3501.rs:12:20: 12:21 error: illegal borrow: borrowed value does not live long enough
/Users/nmatsakis/tmp/bug3501.rs:12     push(&mut a.y, &a.x);
                                                       ^
/Users/nmatsakis/tmp/bug3501.rs:10:12: 14:1 note: borrowed pointer must be valid for the anonymous lifetime #1 defined on the block at 10:12...
/Users/nmatsakis/tmp/bug3501.rs:10 fn A() -> A {
/Users/nmatsakis/tmp/bug3501.rs:11     let a = A { x: ~1, y: ~[] };
/Users/nmatsakis/tmp/bug3501.rs:12     push(&mut a.y, &a.x);
/Users/nmatsakis/tmp/bug3501.rs:13     a
/Users/nmatsakis/tmp/bug3501.rs:14 }
/Users/nmatsakis/tmp/bug3501.rs:10:12: 14:1 note: ...but borrowed value is only valid for the block at 10:12
/Users/nmatsakis/tmp/bug3501.rs:10 fn A() -> A {
/Users/nmatsakis/tmp/bug3501.rs:11     let a = A { x: ~1, y: ~[] };
/Users/nmatsakis/tmp/bug3501.rs:12     push(&mut a.y, &a.x);
/Users/nmatsakis/tmp/bug3501.rs:13     a
/Users/nmatsakis/tmp/bug3501.rs:14 }
error: aborting due to previous error

@graydon
Copy link
Contributor

graydon commented Sep 18, 2012

Dupe of #3513, closing.

@graydon graydon closed this as completed Sep 18, 2012
@nikomatsakis
Copy link
Contributor

Closing as dup of #3513.

RalfJung pushed a commit to RalfJung/rust that referenced this issue Apr 25, 2024
add a test for the TLS memory leak

This is a regression test for rust-lang#123583.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-lifetimes Area: Lifetimes / regions A-type-system Area: Type system
Projects
None yet
Development

No branches or pull requests

3 participants