-3

I am using cython to use python functions in c++, which itself calls a c++ function, Everything compiled perfectly well, but in the end step the error occurs: Segmentation fault (core dumped) when running the out file, I know its a tough ask to find the mistake but can someone please help me:

#include  <iostream>
#include  "Python.h"
#include  "./plugins/strat_plugin.h" //cython generated header file
int main(int argc, char  *argv[])
{
    PyRun_SimpleString("import sys\n" "import os"); 
PyRun_SimpleString("sys.path.append( os.path.dirname(os.getcwd()) +'/plugins/')");
int status=PyImport_AppendInittab("start_plugin", &initstrat_plugin);
if(status==-1){
    std::cout<<"error in appendinit"<<"\n";
    return -1;//error
} 
Py_Initialize();
PyObject *module = PyImport_ImportModule("strat_plugin");
if(module==NULL){
    PyErr_Print();
    Py_Finalize();
    std::cout<<"error in import"<<"\n";
    return -1;//error
}
    long long ans=0;
    std::list<int> a;
    ans=gen_fibonacci(a,1,100); //this is the cython function
    std::cout<<"ans: "<<ans;
    std::cout<<"\n";
}

compile:

g++-8 ./plugins/strat_plugin.c helper.cpp $(python-config --libs)  $(python-config --includes)  $(python-config --cflags)

strat_plugin.pyx file:

from libcpp.list cimport list
from test import test_sum

cdef public long long gen_fibonacci(list[int] &l,int ind,int  n):
    num = 3
    t1 = 0 
    t2 = 1
    nextTerm = 0
    i=1
    if ind==1:
        l.push_back(0)
        l.push_back(1)
        i=3
    if ind==2:
        l.push_back(1)
        i=2
    while i<n:
        nextTerm=t1+t2
        t1=t2
        t2=nextTerm
        if num>=ind:
            i=i+1
            l.push_back(nextTerm)
        num=num+1
    return test_sum(l)

This compiles well with the command: cython -2 strat_plugin.pyx producing header and the c file.

strat.h:

#pragma once

#include <iostream>
#include <list>
long long sum(std::list<int> &);

strategy.cpp

include "strat.h"

using namespace std;

long long sum(list<int> &l)
{
    long long s =0;
    for(list<int>::const_iterator i = l.begin(); i != l.end(); i++)
    s+= *i ;
    return s;
}

strat.pyx:

from libcpp.list cimport list

cdef extern from "strat.h":
    long long sum(list[int] &)

def test_sum(list[int] l):
    return sum(l)

setup.py:

from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext

ext_modules = [Extension("test", ["strat.pyx", "strategy.cpp"], language='c++',)]

setup(cmdclass = {'build_ext': build_ext}, ext_modules = ext_modules)

compile using:

python3 setup.py build_ext --inplace

more relevant information: I tried debugging it with gdb and get this:

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7a2569b in PyImport_GetModuleDict () from /usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0

I don't really get the error can someone point out what's wrong?

Community
  • 1
  • 1
  • 1
    Why does this have to do with c? – user12986714 May 06 '20 at 20:43
  • 5
    "Rightly compiled code" -- All that means is that there are no syntax errors. It has nothing to do with how your code will behave at runtime, whether it has logical errors or not. – PaulMcKenzie May 06 '20 at 20:43
  • There's no way to replicate this without `test_sum`. – David Schwartz May 06 '20 at 20:46
  • Also, you should see if there is an issue with `test_sum` by commenting it out and returning `1` or some other value. If there is no segmentation fault, then `test_sum` is more than likely the issue. In general, you should debug this by divide and conquer, to see what finally works when code is removed. – PaulMcKenzie May 06 '20 at 20:49
  • As the duplicate says: from Python3.5 onwards use `PyImport_AppendInittab` rather than calling `PyInit_*` directly. [The documentation has recently been updated to give a clearer example](https://cython.readthedocs.io/en/latest/src/tutorial/embedding.html) – DavidW May 07 '20 at 06:49
  • I tried that too, see the updated code now, it does not show any error till importing, it just gives segmentation fault – Deepansh Nagaria May 07 '20 at 06:59
  • I've reopened the question because it looks like [the proposed duplicate](https://stackoverflow.com/questions/55647555/calling-cython-function-from-c-code-raises-segmentation-fault?noredirect=1&lq=1) doesn't solve all your problems. – DavidW May 07 '20 at 07:09

1 Answers1

1

Removing test_sum (since I don't have the code to it), ignoring the overflow error (your python code exceeds the range of an int in the while loop), and changing PyInit_strat_plugin to initstrat_plugin, it works fine for me.

David Schwartz
  • 179,497
  • 17
  • 214
  • 278
  • 1
    `PyInit_strat_plugin` -> `initstrat_plugin` is difference between Python 2 and 3. Obviously given OP doesn't say which they were using it's anyone's guess... – DavidW May 06 '20 at 21:20
  • @David Schwartz I have tested test_sum, it is not causing any issues, actually it is a c++ function, compiles to so file using python, I have tested it in shell and it works perfectly fine – Deepansh Nagaria May 07 '20 at 05:23
  • If it's not causing issues then it should not be part of an [mre]; It's a distraction we have to wade through – DavidW May 07 '20 at 05:40
  • @David I looked at your answer and tried to return 0 instead of test_sum(l), but the error still is there.... can you tell me how exactly you ignored test_sum? – Deepansh Nagaria May 07 '20 at 07:01
  • @DeepanshNagaria That's how I did it. I made it return a constant and I removed the `import` statement. But you need to ask a new question. If you could replicate the error without `test_sum`, why did you include it in your question in the first place? You need to ask about *ONLY* what's causing your problem or we have no idea what to look at. Keep removing things until you either have *very* simple code containing only what's causing the problem or you identify the one specific thing causing the problem and remove everything else. – David Schwartz May 07 '20 at 17:56