Skip to content

Segfault in a compiler-generated Drop impl #29092

Closed
@emberian

Description

@emberian

I've tried reducing this code in various ways, and unfortunately the original seems to already be the smallest that fails! Removing variants from Term causes it to not exhibit itself, as does removing cases from the outer match in small_eval. It reproduces on latest nightly only if debuginfo=2, but on older nightlies (@Aatch reports a repro on 2015-09-22) or 1.3.0 it repros for debuginfo=1. On all versions, doing optimizations causes the issue to disappear.

use self::Term::*;

#[derive(Clone)]
pub enum Term {
    True,
    False,
    If(Box<Term>, Box<Term>, Box<Term>),
    Succ(Box<Term>),
    Pred(Box<Term>),
    IsZero(Box<Term>),
}

fn isnumeric(v: &Term) -> bool {
    match *v {
        Pred(ref f) | Succ(ref f) => isnumeric(f),
        _ => false
    }
}

// a small-step evaluator
pub fn small_eval(v: &Term) -> Term {
    match *v {
        If(ref con, ref the, ref els) => match **con {
            True => *the.clone(),
            False => *els.clone(),
            _ => If(Box::new(small_eval(con)), the.clone(), els.clone()),
        },
        Succ(ref s) => Succ(Box::new(small_eval(s))),
        Pred(ref s) => match **s {
            Succ(ref v) if isnumeric(v) => {
                *v.clone()
            },
            _ => Pred(Box::new(small_eval(s))),
        },
        IsZero(ref s) => match **s {
            Succ(ref s) if isnumeric(s) => False,
            _ => IsZero(Box::new(small_eval(s))),
        },
        _ => v.clone()
    }
}

fn main() {
    let t = If(Box::new(True), Box::new(True), Box::new(True));
    small_eval(&t);
}

I suspect that an alloca (forced by debuginfo) is getting trampled somewhere.

GDB backtrace (from rustc 1.5.0-nightly (eafe106 2015-10-15)):

(gdb) run
Starting program: /tmp/foo 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/usr/lib/libthread_db.so.1".

Program received signal SIGSEGV, Segmentation fault.
0x0000555555558b14 in Term::drop.3510::ha59bcdf39bbe7497 ()
(gdb) where
#0  0x0000555555558b14 in Term::drop.3510::ha59bcdf39bbe7497 ()
#1  0x0000555555558af2 in Box$LT$Term$GT$::drop.3508::h48a2557aadc5bcd2 ()
#2  0x00005555555592c1 in foo::small_eval (v=0x7fffffffdb08) at foo.rs:25
#3  0x0000555555559a06 in foo::main () at foo.rs:49
#4  0x000055555555f525 in sys_common::unwind::try::try_fn::h16668888951888304395 ()
#5  0x000055555555d1b9 in __rust_try ()
#6  0x000055555555f1c0 in rt::lang_start::ha93496369c7c61cfF5w ()
#7  0x0000555555559b1a in main ()

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-codegenArea: Code generationI-crashIssue: The compiler crashes (SIGSEGV, SIGABRT, etc). Use I-ICE instead when the compiler panics.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions