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

Checking for uninitialized memory #85

Open
LTLA opened this issue Jan 8, 2025 · 0 comments
Open

Checking for uninitialized memory #85

LTLA opened this issue Jan 8, 2025 · 0 comments

Comments

@LTLA
Copy link
Contributor

LTLA commented Jan 8, 2025

pybind11::array_t constructors don't zero their allocated memory, which can expose subtle bugs in the underlying libraries that (incorrectly) assumed that the input arrays were zeroed. To flush out these bugs, we can just modify the pybind11 code to fill the allocated arrays with some obvious nonsense:

    explicit array_t(ShapeContainer shape, const T *ptr = nullptr, handle base = handle())
        : array_t(private_ctor{},
                  std::move(shape),
                  (ExtraFlags & f_style) != 0 ? detail::f_strides(*shape, itemsize())
                                              : detail::c_strides(*shape, itemsize()),
                  ptr,
                  base) {

        // Aaron's custom crap to smoke out uninitialized values.
        if (ptr) {
            auto buff = request();
            std::fill_n(reinterpret_cast<T*>(buff.ptr), buff.size, []{
                if constexpr(std::is_integral<T>::value) {
                    return -1;
                } else {
                    return std::numeric_limits<T>::quiet_NaN();
                }
            }());
        }
    }

    explicit array_t(ssize_t count, const T *ptr = nullptr, handle base = handle())
        : array({count}, {}, ptr, base) {
        // Aaron's custom crap to smoke out uninitialized values.
        if (!ptr) {
            auto buff = request();
            std::fill_n(reinterpret_cast<T*>(buff.ptr), buff.size, []{
                if constexpr(std::is_integral<T>::value) {
                    return 100;
                } else {
                    return std::numeric_limits<T>::quiet_NaN();
                }
            }());
        }
    }

and then check that the tests still work correctly. (Most tests involve an equality check that should fail if it encounters NaNs, or bounds checks for integers.)

MSan might also catch this but it seems tedious to get it to work with Python.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant