Giter Site home page Giter Site logo

Rust's newly added `assert_unsafe_precondition` makes GDNative .dlls that are compiled in debug mode crash on startup about gdnative HOT 4 OPEN

Houtamelo avatar Houtamelo commented on July 17, 2024
Rust's newly added `assert_unsafe_precondition` makes GDNative .dlls that are compiled in debug mode crash on startup

from gdnative.

Comments (4)

mivort avatar mivort commented on July 17, 2024 1

Starting from Rust 1.78, debug builds now check for null pointer in slice_from_raw_parts method, so now it seems to crash on start here (null pointer gets passed along with zero length for empty slices):

pub unsafe fn from_sys(num_args: libc::c_int, args: *mut *mut sys::godot_variant) -> Self {
let args = std::slice::from_raw_parts(args, num_args as usize);
let args = std::mem::transmute::<&[*mut sys::godot_variant], &[&Variant]>(args);

The rationale for considering null pointers invalid for zero-length slices is that Option monad is optimized on compiler level in a way that zero-values are considered as None (so if zero-length slice is constructed from 0x0/0x0 parts, it would be matched as None instead of Some() inside of Option). It's perfectly fine to pass any non-null bogus, e.g. 0x1 etc.

I'm currently using this a quick workaround:

let args = if num_args > 0 { std::slice::from_raw_parts(args, num_args as usize) } else { &[] };

...but it may be sub-optimal, as it adds a branching condition in a pretty hot path. So maybe there's a better way to introduce a validation for zero-length slices and prevent passing null as args.

from gdnative.

BenjiFlaming avatar BenjiFlaming commented on July 17, 2024 1

Iterating on the workaround, I've adjusted my copy of method.rs to include the original code in release builds (and the workaround in debug builds). Not necessarily the best way to do it, but sharing in case it's helpful:

    pub unsafe fn from_sys(num_args: libc::c_int, args: *mut *mut sys::godot_variant) -> Self {
        let args = Self::safe_args(num_args, args);
        let args = std::mem::transmute::<&[*mut sys::godot_variant], &[&Variant]>(args);
        Self {
            idx: 0,
            args,
            offset_index: 0,
        }
    }

    /// Convert args to a slice in debug builds - avoids crash when using Rust 1.78 and beyond
    #[doc(hidden)]
    #[inline]
    #[cfg(debug_assertions)]
    unsafe fn safe_args(
        num_args: libc::c_int,
        args: *mut *mut sys::godot_variant,
    ) -> &'a [*mut sys::godot_variant] {
        if num_args > 0 {
            std::slice::from_raw_parts(args, num_args as usize)
        } else {
            &[]
        }
    }

    /// Convert args to a slice in release builds - using more effecient code than the version above
    #[doc(hidden)]
    #[inline]
    #[cfg(not(debug_assertions))]
    unsafe fn safe_args(
        num_args: libc::c_int,
        args: *mut *mut sys::godot_variant,
    ) -> &'a [*mut sys::godot_variant] {
        std::slice::from_raw_parts(args, num_args as usize)
    }

from gdnative.

BenjiFlaming avatar BenjiFlaming commented on July 17, 2024

Can confirm that I'm experiencing this under Ubuntu 20.04 (Linux 64-bit) with Rust 0.78.0 and Godot 3.5.3.

Can also confirm that the workaround fixed the crash here - thanks so much for sharing it! :)

from gdnative.

bend-n avatar bend-n commented on July 17, 2024

the only way to avoid such a branch is by simply keeping it as a pointer, instead of turning it into a slice, but that would take some work.

from gdnative.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.