Numpy C ++程序总是提供segfault(最可能滥用语法或类型) [英] Numpy C++ program always gives segfault (most likely misuse of syntax or types)

查看:143
本文介绍了Numpy C ++程序总是提供segfault(最可能滥用语法或类型)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发我的第一个C ++扩展为一个python程序。我一直在试图调试这个特定的代码小时,我的想法。



segfault似乎与 PyArrayObject old_simplices_array 即将传递给C ++代码。该对象是 uint32 类型的 2d numpy数组



这段代码直接从 scipy.weave 放在一起修改。一切工作正常,当代码格式化和由scipy.weave.inline使用。这似乎消除了我的程序的python部分和算法本身从可能的罪魁祸首。



只保留语法和类型。有没有人看到任何不正确的语法或类型转换代码?

  static PyObject * exterior(PyObject * self,
PyArrayObject * old_simplices_array)
{
const short unsigned int step = old_simplices_array-> dimensions [1];
const short unsigned int j_max = step-1;
const long unsigned int col_max =
old_simplices_array-> dimensions [0] * step;
short unsigned int j,k,face_index;
long unsigned int col;
unsigned int num_simplices = 0;

PyObject * indices = PyList_New(0);
PyObject * indptr = PyList_New(0);
PyObject * data = PyList_New(0);
PyObject * simplices = PyList_New(0);
PyList_Append(indptr,PyLong_FromLong(0));
PyObject * simplex_to_index = PyDict_New();

for(col = 0; col< col_max; col + = step)
{
for(j = 0; j <= j_max; j ++)
{
face_index = 0;
PyObject * face = PyTuple_New(j_max);
for(k = 0; k <= j_max; k ++)
{
if(j!= k)
{
PyTuple_SetItem(face,face_index,
PyLong_FromLong(old_simplices_array-> data [col + k]));
face_index ++;
}
}

if(PyDict_Contains(simplex_to_index,face))
{
PyList_Append(indices,
PyDict_GetItem(simplex_to_index,face) );
}
else
{
PyDict_SetItem(simplex_to_index,face,
PyLong_FromLong(num_simplices));
PyList_Append(simplices,face);
num_simplices ++;
}
PyList_Append(data,PyLong_FromLong(1-2 *(j%2)));
}
PyList_Append(indptr,PyLong_FromLong(col + j));
}
return PyTuple_Pack(3,PyTuple_Pack(3,data,indices,indptr),simplices,
simplex_to_index);
}

- UPDATE

gdb表示

  const short unsigned int步骤= old_simplices_array-> dimensions [1]; 

会导致segfault。我滥用了类型吗?



------ UPDATE ------ $ b

尽管GDB告诉我,



const short unsigned int step = old_simplices_array-> dimensions [1];



导致segfault,如果我从程序在for循环之前返回,我没有segfault(只是一个错误在python一方抱怨返回None Type)。



这是完整的追踪:

 信号SIGSEGV,分段故障。 
exterior(self =< optimized out>,old_simplices_array = 0xec0a50)
at src / _alto.cpp:39
警告:源文件比可执行文件更新。
39 const short unsigned int step = old_simplices_array-> dimensions [1];
(gdb)bt
outside(self =< optimized out> old_simplices_array = 0xec0a50)
at src / _alto.cpp:39
0x00007ffff7aedad2 in PyEval_EvalFrameEx b从/usr/lib/sagemath/local/lib/libpython2.7.so.1.0
0x00007ffff7aeddc9在PyEval_EvalFrameEx()
从/usr/lib/sagemath/local/lib/libpython2.7.so .1.0
0x00007ffff7aee902在PyEval_EvalCodeEx()
从/usr/lib/sagemath/local/lib/libpython2.7.so.1.0
0x00007ffff7a70ad6在?? ()
从/usr/lib/sagemath/local/lib/libpython2.7.so.1.0
0x00007ffff7a4565e在PyObject_Call()
从/ usr / lib / sagemath / local / lib / libpython2.7.so.1.0
0x00007ffff7a53b80 in? ()
从/usr/lib/sagemath/local/lib/libpython2.7.so.1.0
0x00007ffff7a4565e在PyObject_Call()
从/ usr / lib / sagemath / local / lib / libpython2.7.so.1.0
0x00007ffff7aaaea0在?? ()
从/usr/lib/sagemath/local/lib/libpython2.7.so.1.0
0x00007ffff7aa6​​8bc在?? ()
从/usr/lib/sagemath/local/lib/libpython2.7.so.1.0
0x00007ffff7a4565e在PyObject_Call()
从/ usr / lib / sagemath / local / lib / libpython2.7.so.1.0
0x00007ffff7ae9bce在PyEval_EvalFrameEx()
从/usr/lib/sagemath/local/lib/libpython2.7.so.1.0
0x00007ffff7aee902在PyEval_EvalCodeEx()
从/usr/lib/sagemath/local/lib/libpython2.7.so.1.0
0x00007ffff7aeea32在PyEval_EvalCode()
从/usr/lib/sagemath/local/lib/libpython2.7。 so1.0
0x00007ffff7b103fa在PyRun_FileExFlags()
从/usr/lib/sagemath/local/lib/libpython2.7.so.1.0
0x00007ffff7b10e3d在PyRun_SimpleFileExFlags()
从/ usr / lib / sagemath / local / lib / libpython2.7.so.1.0
0x00007ffff7b26972在Py_Main()
从/usr/lib/sagemath/local/lib/libpython2.7.so.1.0
0x00007ffff6d29ea5在__libc_start_main()
从/lib/x86_64-linux-gnu/libc.so.6
0x00000000004006d1在_start()


解决方案

一般来说,C模块中的方法的签名是 PyObject * f self,PyObject * args),其中 args 旨在由 PyArg_ParseTuple 你可以在代码 scipy.weave 中看到这一点: http://docs.scipy.org/doc/scipy/reference/tutorial/weave.html#a-quick-look-at-代码)。除非有一些包装函数,你还没有发布调用 PyArg_ParseTuple ,你的 exterior 方法必须调用它来提取来自通用 PyObject * args PyArrayObject


I'm working on my first C++ extension for a python program. I have been trying to debug this particular piece of code for hours and I am out of ideas.

The segfault seems to have something to do with the PyArrayObject old_simplices_array that is getting passed to the C++ code. That object is a 2d numpy array of type uint32.

This code was modified directly from what scipy.weave puts together. Everything works fine when the code is formatted for and used by scipy.weave.inline. This seems to eliminate the python portion of my program and the algorithm itself from being possible culprits.

That just leaves the syntax and types. Does anyone see any incorrect syntax or type casting the code?

static PyObject* exterior(PyObject* self,
                          PyArrayObject* old_simplices_array)
{
    const short unsigned int step = old_simplices_array->dimensions[1];
    const short unsigned int j_max = step - 1;
    const long unsigned int col_max = 
        old_simplices_array->dimensions[0] * step;
    short unsigned int j, k, face_index;
    long unsigned int col;
    unsigned int num_simplices = 0;

    PyObject* indices = PyList_New(0);
    PyObject* indptr =  PyList_New(0);
    PyObject* data =  PyList_New(0);
    PyObject* simplices = PyList_New(0);
    PyList_Append(indptr, PyLong_FromLong(0));
    PyObject* simplex_to_index = PyDict_New();

    for(col = 0; col < col_max; col+=step)
    {
        for(j = 0; j <= j_max; j++)
        {
            face_index = 0;
            PyObject* face = PyTuple_New(j_max);
            for(k = 0; k <= j_max; k++)
            {
                if(j != k)
                {
                    PyTuple_SetItem(face, face_index, 
                        PyLong_FromLong(old_simplices_array->data[col + k]));
                    face_index++;
                }
            }

            if(PyDict_Contains(simplex_to_index, face))
            {
                PyList_Append(indices, 
                    PyDict_GetItem(simplex_to_index, face));
            }
            else
            {
                PyDict_SetItem(simplex_to_index, face, 
                    PyLong_FromLong(num_simplices));
                PyList_Append(simplices, face);
                num_simplices++;
            }
            PyList_Append(data, PyLong_FromLong(1 - 2 * (j % 2)));
        }
        PyList_Append(indptr, PyLong_FromLong(col + j));
    }
    return PyTuple_Pack(3, PyTuple_Pack(3, data, indices, indptr), simplices,
        simplex_to_index);
}                                

------UPDATE------

gdb indicates

const short unsigned int step = old_simplices_array->dimensions[1];

causes a segfault. Did I misuse types?

------UPDATE------

Despite GDB telling me,

const short unsigned int step = old_simplices_array->dimensions[1];

causes the segfault, if I return from the program just before the for loop, I get no segfault (just an error on the python side complaining about returning a NoneType).

This is the full backtrace:

Program received signal SIGSEGV, Segmentation fault.
exterior (self=<optimized out>, old_simplices_array=0xec0a50)
    at src/_alto.cpp:39
warning: Source file is more recent than executable.
39      const short unsigned int step = old_simplices_array->dimensions[1];
(gdb) bt
exterior (self=<optimized out>, old_simplices_array=0xec0a50)
    at src/_alto.cpp:39
0x00007ffff7aedad2 in PyEval_EvalFrameEx ()
   from /usr/lib/sagemath/local/lib/libpython2.7.so.1.0
0x00007ffff7aeddc9 in PyEval_EvalFrameEx ()
   from /usr/lib/sagemath/local/lib/libpython2.7.so.1.0
0x00007ffff7aee902 in PyEval_EvalCodeEx ()
   from /usr/lib/sagemath/local/lib/libpython2.7.so.1.0
0x00007ffff7a70ad6 in ?? ()
   from /usr/lib/sagemath/local/lib/libpython2.7.so.1.0
0x00007ffff7a4565e in PyObject_Call ()
   from /usr/lib/sagemath/local/lib/libpython2.7.so.1.0
0x00007ffff7a53b80 in ?? ()
   from /usr/lib/sagemath/local/lib/libpython2.7.so.1.0
0x00007ffff7a4565e in PyObject_Call ()
   from /usr/lib/sagemath/local/lib/libpython2.7.so.1.0
0x00007ffff7aaaea0 in ?? ()
   from /usr/lib/sagemath/local/lib/libpython2.7.so.1.0
0x00007ffff7aa68bc in ?? ()
   from /usr/lib/sagemath/local/lib/libpython2.7.so.1.0
0x00007ffff7a4565e in PyObject_Call ()
   from /usr/lib/sagemath/local/lib/libpython2.7.so.1.0
0x00007ffff7ae9bce in PyEval_EvalFrameEx ()
   from /usr/lib/sagemath/local/lib/libpython2.7.so.1.0
0x00007ffff7aee902 in PyEval_EvalCodeEx ()
   from /usr/lib/sagemath/local/lib/libpython2.7.so.1.0
0x00007ffff7aeea32 in PyEval_EvalCode ()
   from /usr/lib/sagemath/local/lib/libpython2.7.so.1.0
0x00007ffff7b103fa in PyRun_FileExFlags ()
   from /usr/lib/sagemath/local/lib/libpython2.7.so.1.0
0x00007ffff7b10e3d in PyRun_SimpleFileExFlags ()
   from /usr/lib/sagemath/local/lib/libpython2.7.so.1.0
0x00007ffff7b26972 in Py_Main ()
   from /usr/lib/sagemath/local/lib/libpython2.7.so.1.0
0x00007ffff6d29ea5 in __libc_start_main ()
   from /lib/x86_64-linux-gnu/libc.so.6
0x00000000004006d1 in _start ()

解决方案

In general, the signature of a method in a C module is PyObject* f(PyObject* self, PyObject* args), where args is intended to be parsed by PyArg_ParseTuple. You can see this in the code scipy.weave generates: http://docs.scipy.org/doc/scipy/reference/tutorial/weave.html#a-quick-look-at-the-code). Unless there's some wrapper function you haven't posted that calls PyArg_ParseTuple for you, your exterior method must call it to extract the PyArrayObject from the generic PyObject* args.

这篇关于Numpy C ++程序总是提供segfault(最可能滥用语法或类型)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆