-1

EDITED:

I am trying to bind the function that is allocating

#include <iostream>
#include <vector>
#include "pybind11/numpy.h"
#include <pybind11/stl.h>
#include <pybind11/stl_bind.h>

struct Dummy {
    Dummy() : data1(1), data2(2) {};
    int data1;
    int data2;
};

struct DummyProcessor {
    DummyProcessor() {};
    int processData() 
    {
        Dummy tmpArr[700000]; 
        // no SEGFAULT if this number is lower 
        // or if DummyProcessor instance is created directly in C++
        return 0;
    }
};

PYBIND11_MODULE(test_binding, m) {
    m.doc() = "pybind11 example plugin";
    
    pybind11::class_<Dummy>(m, "Dummy") 
        .def(pybind11::init<>())
        ;
        
    pybind11::class_<DummyProcessor>(m, "DummyProcessor") 
        .def(pybind11::init<>())
        .def("processData", [](DummyProcessor& self)
        {
            int status = self.processData();
            return status;
        })
        ;
}

CMakeLists.txt:

cmake_minimum_required(VERSION 3.14)
project(test)
include(FetchContent)
FetchContent_Declare(
    pybind11
    GIT_REPOSITORY https://github.com/pybind/pybind11.git
)
FetchContent_MakeAvailable(pybind11)
pybind11_add_module(test_binding test.cpp)
target_compile_options(test_binding BEFORE PRIVATE -D_hypot=hypot)

Compiling (add your compiler path):

cmake -G "MinGW Makefiles" -DCMAKE_CXX_COMPILER=PATH_TO_MINGW/g++.exe -DCMAKE_BUILD_TYPE=Debug
PATH_TO_MINGW\mingw32-make.exe Makefile test_binding

Trying to call binding in Python:

import test_binding as t
proc = t.DummyProcessor()
proc.processData()  # SEGFAULT
Valeria
  • 1,508
  • 4
  • 20
  • 44
  • 1
    VTC as typo `for (int i = 0; i < numPointsIn; i++)` ; Nothing to do with python bindings, that wouldn't work with pure c++ neither (but it's UB, so anything might happen). – pptaszni Aug 30 '23 at 14:14
  • Specifically in `processData`, causing OOB access to both `data_out` and `data_in`. – Dan Mašek Aug 30 '23 at 14:41
  • @pptaszni indeed. However, that typo is only present in the example I tried to create, it is not present in the actual code. It now seems that segfault is caused by allocating additional array exceeding some limit in the original C++ function. So running out of memory? This is not present when calling pure C++ though. – Valeria Aug 30 '23 at 14:45
  • 1
    @Valeria OK, then please [edit] your question, so that the code presented doesn't contain more mistakes and typos, and properly represents the "actual code". | "running out of memory" -- by allocating few hundred 8-byte structs? Doesn't seem likely. – Dan Mašek Aug 30 '23 at 15:16
  • 1
    @Valeria somehow when I corrected the typo, the crash is no longer reproducible, c++ works ok, python works ok as well. – pptaszni Aug 30 '23 at 15:22
  • Also, is the `numPointsIn` argument in the bindings necessary? Both Python lists and `std::vector` track their own size, so it seems like duplication. If it is required, than I'd at least suggest adding some validation in the bindings, to catch invalid values (negative, or too large) early. – Dan Mašek Aug 30 '23 at 15:22
  • @pptaszni yes, the minimum example was not correctly illustrating the issue, my apologies. I changed it to have just `processData()` which allocates an array. Issue is described in text but just to summarize: allocating this array when calling from Python creates segfault. Creation of a `DummyProcessor` instance in pure C++ and calling the same function do not result in the segfault. Changing stacksize in `CMakeLists.txt` did not have influence on this issue. Reducing size of array removes the segfault. – Valeria Aug 30 '23 at 15:50
  • 1
    Just don't create such large arrays on stack. – Dan Mašek Aug 30 '23 at 16:06

0 Answers0