Skip to content

Display in test fails with SIGILL (illegal instruction) #69558

@SnowyCoder

Description

@SnowyCoder

I tried this code (using cargo test):

use std::fmt::{Display, Formatter};
use std::fmt;
 
pub struct A(Vec<u32>);
 
impl Display for A {
    fn fmt(&self, _f: &mut Formatter<'_>) -> fmt::Result {
       self.0[0];
       Ok(())
   }
}
 
#[test]
fn main() {
   let a = A(vec![]);
   eprintln!("{}", a);
}

I expected to see this happen:
The thread should've panicked with 'Index out of bounds: the len is 0 but the index is 0'

Instead, this happened:
Thread crashes with SIGILL (illegal instruction)

Meta

This bug works in stable, beta and nightly.
It also does the same in rust playground.
Here is my cpu info (I figured that it might be useful given the nature of the bug).
The bug doesn't appear if run from main, nor if run directly (without passing from the Display impl).

rustc --version --verbose:

rustc 1.41.1 (f3e1a954d 2020-02-24)
binary: rustc
commit-hash: f3e1a954d2ead4e2fc197c7da7d71e6c61bad196
commit-date: 2020-02-24
host: x86_64-unknown-linux-gnu
release: 1.41.1
LLVM version: 9.0
Backtrace

running 1 test
thread panicked while processing panic. aborting.
error: test failed, to rerun pass '--lib'

Caused by:
process didn't exit successfully: /path/to/proj/target/debug/deps/proj-296b7cb53c6210d6 (signal: 4, SIGILL: illegal instruction)

Activity

jonas-schievink

jonas-schievink commented on Feb 28, 2020

@jonas-schievink
Contributor

This seems to be due to the eprintln!. Using format! instead works fine.

added
A-libtestArea: `#[test]` / the `test` library
T-libs-apiRelevant to the library API team, which will review and decide on the PR/issue.
on Feb 28, 2020
added
I-crashIssue: The compiler crashes (SIGSEGV, SIGABRT, etc). Use I-ICE instead when the compiler panics.
on Feb 28, 2020
Mark-Simulacrum

Mark-Simulacrum commented on Feb 28, 2020

@Mark-Simulacrum
Member

I can reproduce. This seems to happen if LOCAL_STDERR is initialized (e.g., with set_panic) which leads us to this code. Note that the RefCell there is borrowed so that we can write to it, but then when we go to panic we try to temporarily take the value out. This borrows the RefCell mutably, again, leading to a panic. Since this happens within an existing panic, we abort the process.

Smaller example:

#![feature(set_stdio, print_internals)]

use std::fmt::{Display, Formatter};
use std::fmt;
use std::io::set_panic;

pub struct A;

impl Display for A {
    fn fmt(&self, _f: &mut Formatter<'_>) -> fmt::Result {
        panic!();
   }
}

fn main() {
    set_panic(Some(Box::new(Vec::new())));
    std::io::_eprint(format_args!("{}", A));
}
added a commit that references this issue on Mar 13, 2020
7d31795
added a commit that references this issue on Mar 14, 2020
33ae90e
added a commit that references this issue on Mar 17, 2020
773c04c
added a commit that references this issue on Mar 17, 2020
63e67ce
added a commit that references this issue on Mar 18, 2020
d5b6a20
added 2 commits that reference this issue on Mar 19, 2020
b4098a1
73c3a49
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

    A-libtestArea: `#[test]` / the `test` libraryC-bugCategory: This is a bug.I-crashIssue: The compiler crashes (SIGSEGV, SIGABRT, etc). Use I-ICE instead when the compiler panics.T-libs-apiRelevant to the library API team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      Participants

      @jonas-schievink@Mark-Simulacrum@SnowyCoder

      Issue actions

        Display in test fails with SIGILL (illegal instruction) · Issue #69558 · rust-lang/rust