zesterer / euc

A software rendering crate that lets you write shaders with Rust
Apache License 2.0
294 stars 15 forks source link

Segmentation fault when using infinite coordinates in release mode #21

Open aweinstock314 opened 2 years ago

aweinstock314 commented 2 years ago
use euc::{buffer::Buffer2d, Pipeline};

#[derive(Default)]
struct Model {
    xs: Vec<f32>,
    ys: Vec<f32>,
    zs: Vec<f32>,
}

impl Model {
    fn push_point(&mut self, x: f32, y: f32, z: f32) {
        self.xs.push(x);
        self.ys.push(y);
        self.zs.push(z);
    }
}

impl Pipeline for Model {
    type Vertex = usize;
    type VsOut = ();
    type Pixel = [u8; 4];

    fn vert(&self, pos: &Self::Vertex) -> ([f32; 4], Self::VsOut) {
        let x = self.xs[*pos];
        let y = self.ys[*pos];
        let z = self.zs[*pos];
        // The 0.0 here is incorrect, replacing it with 1.0 correctly draws a triangle.
        ([x, y, z, 0.0], ())
    }

    fn frag(&self, _: &Self::VsOut) -> Self::Pixel {
        [255, 0, 0, 255]
    }
}

fn main() {
    let mut model = Model::default();
    model.push_point(0.0, 0.0, 0.0);
    model.push_point(1.0, 0.0, 0.0);
    model.push_point(0.0, 1.0, 0.0);
    let mut buffer = Buffer2d::new([640, 480], [0, 0, 0, 255]);
    model.draw::<euc::rasterizer::Triangles<(f32,)>, _>(&[0,1,2], &mut buffer, None);
}
$ cargo run
   Compiling euc_soundness_issue v0.1.0 (/home/avi/git-repos/euc_soundness_issue)
    Finished dev [unoptimized + debuginfo] target(s) in 0.30s
     Running `target/debug/euc_soundness_issue`
thread 'main' panicked at 'assertion failed: fb_to_weights.into_row_array().iter().all(|e| e.is_finite())', /home/avi/.cargo/registry/src/github.com-1ecc6299db9ec823/euc-0.5.3/src/rasterizer/triangles.rs:97:13
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
$ cargo build --release
    Finished release [optimized] target(s) in 0.01s
$ gdb ./target/release/euc_soundness_issue
GNU gdb (Gentoo 11.2 vanilla) 11.2
Copyright (C) 2022 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-pc-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://bugs.gentoo.org/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./target/release/euc_soundness_issue...
(gdb) r
Starting program: /home/avi/git-repos/euc_soundness_issue/target/release/euc_soundness_issue
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".

Program received signal SIGSEGV, Segmentation fault.
0x000055555555c57c in <euc::rasterizer::triangles::Triangles<D,B> as euc::rasterizer::Rasterizer>::draw ()
(gdb) bt
#0  0x000055555555c57c in <euc::rasterizer::triangles::Triangles<D,B> as euc::rasterizer::Rasterizer>::draw ()
#1  0x000055555555c957 in euc_soundness_issue::main ()
#2  0x000055555555b853 in std::sys_common::backtrace::__rust_begin_short_backtrace ()
#3  0x000055555555b899 in std::rt::lang_start::_$u7b$$u7b$closure$u7d$$u7d$::hd86615ae8ae74c2a ()
#4  0x000055555557095b in core::ops::function::impls::{impl#2}::call_once<(), (dyn core::ops::function::Fn<(), Output=i32> + core::marker::Sync + core::panic::unwind_safe::RefUnwindSafe)> ()
    at /rustc/f1edd0429582dd29cccacaf50fd134b05593bd9c/library/core/src/ops/function.rs:259
#5  std::panicking::try::do_call<&(dyn core::ops::function::Fn<(), Output=i32> + core::marker::Sync + core::panic::unwind_safe::RefUnwindSafe), i32> () at library/std/src/panicking.rs:403
#6  std::panicking::try<i32, &(dyn core::ops::function::Fn<(), Output=i32> + core::marker::Sync + core::panic::unwind_safe::RefUnwindSafe)> () at library/std/src/panicking.rs:367
#7  std::panic::catch_unwind<&(dyn core::ops::function::Fn<(), Output=i32> + core::marker::Sync + core::panic::unwind_safe::RefUnwindSafe), i32> () at library/std/src/panic.rs:133
#8  std::rt::lang_start_internal::{closure#2} () at library/std/src/rt.rs:128
#9  std::panicking::try::do_call<std::rt::lang_start_internal::{closure#2}, isize> () at library/std/src/panicking.rs:403
#10 std::panicking::try<isize, std::rt::lang_start_internal::{closure#2}> () at library/std/src/panicking.rs:367
#11 std::panic::catch_unwind<std::rt::lang_start_internal::{closure#2}, isize> () at library/std/src/panic.rs:133
#12 std::rt::lang_start_internal () at library/std/src/rt.rs:128
#13 0x000055555555ca42 in main ()
(gdb) x/i $rip
=> 0x55555555c57c <_ZN98_$LT$euc..rasterizer..triangles..Triangles$LT$D$C$B$GT$$u20$as$u20$euc..rasterizer..Rasterizer$GT$4draw17ha366b0ce9b0fe719E+2812>:      movl   $0xff0000ff,(%rax,%rbx,4)
(gdb) i r rax rbx
rax            0x7ffff7b50010      140737349222416
rbx            0x4bbfc             310268