Skip to content

Panic within a panic causes illegal instruction SIGILL #53814

Closed
@sunjay

Description

@sunjay

See first comment for an even smaller example of the issue. Thanks @mgattozzi for the insight that led to that!

I was integrating NonZeroU8 into some code when I ran into an illegal instruction error that looks like this:

thread panicked while panicking. aborting.
error: process didn't exit successfully: `/path/to/my/project/target/debug/deps/xxxx-b71130afded4f9e4` (signal: 4, SIGILL: illegal instruction)

I spent a really long time trying to narrow this down and I got down to the following contrived example: (Rust Playground)

use std::{
    fmt,
    num::NonZeroU8,
};

pub struct Foo;

impl fmt::Display for Foo {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", NonZeroU8::new(0).unwrap())
    }
}

#[test]
fn something() {
    panic!("{}", Foo);
}

This probably looks like super weird code that no one would ever write, but this started from some real code I promise. 😆

The key part of this code is:

NonZeroU8::new(0).unwrap()

The illegal instruction error occurs whenever that 0 is any value less than or equal to zero. You may be asking yourself "How do you make a u8 literal less than zero?" Well you don't. Rust protects you from that. The thing that Rust doesn't protect you from is this: (Rust Playground)

let y = 3;
let x = 2 - y;
write!(f, "{}", NonZeroU8::new(x).unwrap())

The variable x will be -1 and the code will produce the same illegal instruction error.

Some weird things to note about this:

  • It seems to work when run with cargo run. The failure is on cargo test.
  • I haven't figured out how to recreate this without the impl of Display. Inlining does NOT produce the error:
// No illegal instructions for this code!
use std::num::NonZeroU8;

#[test]
fn something() {
    panic!("{}", NonZeroU8::new(0).unwrap());
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions