Skip to content
New issue

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

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

Already on GitHub? # 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.
# for free to join this conversation on GitHub. Already have an account? # 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