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

Segmentation fault #117461

Closed
valentinegb opened this issue Oct 31, 2023 · 3 comments
Closed

Segmentation fault #117461

valentinegb opened this issue Oct 31, 2023 · 3 comments
Labels
A-stack-probe Area: Stack probing and guard pages C-discussion Category: Discussion or questions that doesn't represent real issues. O-AArch64 Armv8-A or later processors in AArch64 mode T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@valentinegb
Copy link

I'm very sorry for how little information this bug report has, hopefully just, initially. I'm really not sure what exactly is going wrong here.

I have an Advent of Code project (the whole thing is here) where all the years and days are organized into their own files. This is the code I have in the file dy6.rs (day 6):

use std::str::FromStr;

use anyhow::{anyhow, bail};

#[derive(Debug)]
struct Instruction {
    kind: InstructionKind,
    start: (usize, usize),
    end: (usize, usize),
}

#[derive(Debug)]
enum InstructionKind {
    TurnOn,
    TurnOff,
    Toggle,
}

impl FromStr for Instruction {
    type Err = anyhow::Error;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        let kind = match s {
            i if i.starts_with("turn on") => InstructionKind::TurnOn,
            i if i.starts_with("turn off") => InstructionKind::TurnOff,
            i if i.starts_with("toggle") => InstructionKind::Toggle,
            _ => {
                bail!(r#"string did not start with "turn on", "turn off", or "toggle""#);
            }
        };

        let start_i = match kind {
            InstructionKind::TurnOn => 8,
            InstructionKind::TurnOff => 9,
            InstructionKind::Toggle => 7,
        };
        let through = s
            .find("through")
            .ok_or(anyhow!(r#"instruction should contain "through""#))?;
        let start = s[start_i..(through - 1)]
            .split_once(',')
            .ok_or(anyhow!("coord pairs should be separated with ','"))?;
        let start: (usize, usize) = (start.0.parse()?, start.1.parse()?);
        let end = s[(through + 8)..]
            .split_once(',')
            .ok_or(anyhow!("coord pairs should be separated with ','"))?;
        let end: (usize, usize) = (end.0.parse()?, end.1.parse()?);

        Ok(Instruction { kind, start, end })
    }
}

pub(super) fn pt1(input: String) {
    let mut grid = [[false; 1000]; 1000];

    for instruction in input.split('\n') {
        let instruction = Instruction::from_str(instruction).unwrap();

        for column in instruction.start.0..=instruction.end.0 {
            for row in instruction.start.1..=instruction.end.1 {
                match instruction.kind {
                    InstructionKind::TurnOn => grid[column][row] = true,
                    InstructionKind::TurnOff => grid[column][row] = false,
                    InstructionKind::Toggle => grid[column][row] = !grid[column][row],
                }
            }
        }
    }

    let mut lit_lights: u32 = 0;

    for column in grid {
        for light_lit in column {
            if light_lit {
                lit_lights += 1;
            }
        }
    }

    println!("{lit_lights}");
}

pub(super) fn pt2(input: String) {
    let mut grid: [[u32; 1000]; 1000] = [[0; 1000]; 1000];

    for instruction in input.split('\n') {
        let instruction = Instruction::from_str(instruction).unwrap();

        for column in instruction.start.0..=instruction.end.0 {
            for row in instruction.start.1..=instruction.end.1 {
                match instruction.kind {
                    InstructionKind::TurnOn => grid[column][row] += 1,
                    InstructionKind::TurnOff => {
                        if grid[column][row] > 0 {
                            grid[column][row] -= 1
                        }
                    }
                    InstructionKind::Toggle => grid[column][row] += 2,
                }
            }
        }
    }

    let mut total_brightness: u32 = 0;

    for column in grid {
        for brightness in column {
            total_brightness += brightness;
        }
    }

    println!("{total_brightness}");
}

The function pt1() (part 1) works as expected, but pt2() crashes with a segmentation fault! I tried figuring out where exactly it's failing, and it seems like it's crashing just before pt2() is called.

zsh: segmentation fault  cargo run -- 2015 6 2 "this happens no matter what text is here"

This happens for me on both stable and nightly.

Meta

rustc --version --verbose:

rustc 1.73.0 (cc66ad468 2023-10-03)
binary: rustc
commit-hash: cc66ad468955717ab92600c770da8c1601a4ff33
commit-date: 2023-10-03
host: aarch64-apple-darwin
release: 1.73.0
LLVM version: 17.0.2

No backtrace available.

@valentinegb valentinegb added the C-bug Category: This is a bug. label Oct 31, 2023
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Oct 31, 2023
@saethlin
Copy link
Member

The problem is this

    let mut grid: [[u32; 1000]; 1000] = [[0; 1000]; 1000];

This attempts to create a 4 MB allocation on the stack, which is pushing your luck when the default stack size is 8 MB. You get a segfault because we don't have stack protectors on aarch64.

This should work:

    let mut grid: Vec<[u32; 1000]> = vec![[0; 1000]; 1000];

@saethlin saethlin removed C-bug Category: This is a bug. needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. labels Oct 31, 2023
@Noratrieb Noratrieb added T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. C-discussion Category: Discussion or questions that doesn't represent real issues. O-AArch64 Armv8-A or later processors in AArch64 mode A-stack-probe Area: Stack probing and guard pages labels Oct 31, 2023
@valentinegb
Copy link
Author

Yep, that was it. Thank you! There really ought to be a better error for this though...

@saethlin
Copy link
Member

There will be, when we get support for stack probes on aarch64: #77071

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-stack-probe Area: Stack probing and guard pages C-discussion Category: Discussion or questions that doesn't represent real issues. O-AArch64 Armv8-A or later processors in AArch64 mode T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

4 participants