正确编译的代码(没有错误)给出分段错误核心转储

Posted

技术标签:

【中文标题】正确编译的代码(没有错误)给出分段错误核心转储【英文标题】:Rightly compiled code(without error) giving Segmentation fault core dumped 【发布时间】:2020-05-06 20:38:55 【问题描述】:

我正在使用 cython 在 c++ 中使用 python 函数,它本身调用了一个 c++ 函数,一切都编译得很好,但在最后一步出现错误:Segmentation fault (core dumped) 运行输出文件时,我知道这是一个艰难的问题找出错误,但有人可以帮助我:

#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";

编译:

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

strat_plugin.pyx 文件:

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)

这可以很好地与以下命令一起编译:cython -2 strat_plugin.pyx 生成头文件和 c 文件。

strat.h:

#pragma once

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

策略.cpp

包括“strat.h”

使用命名空间标准;

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)

编译使用:

python3 setup.py build_ext --inplace

更多相关信息: 我尝试用 gdb 调试它并得到这个:

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

我真的不明白错误有人能指出什么问题吗?

【问题讨论】:

为什么和c有关系? "正确编译的代码" -- 这意味着没有语法错误。它与您的代码在运行时的行为方式无关,无论它是否存在逻辑错误。 没有test_sum,就无法复制。 另外,您应该通过注释掉 test_sum 并返回 1 或其他值来查看是否存在问题。如果没有分段错误,那么test_sum 很可能是问题所在。一般来说,您应该通过分而治之的方式进行调试,以查看删除代码后最终会发生什么。 正如副本所说:从 Python3.5 开始使用 PyImport_AppendInittab 而不是直接调用 PyInit_*。 The documentation has recently been updated to give a clearer example 【参考方案1】:

删除test_sum(因为我没有代码),忽略溢出错误(您的python代码超出while循环中的int范围),并将PyInit_strat_plugin更改为@987654325 @,它对我来说很好用。

【讨论】:

PyInit_strat_plugin -> initstrat_plugin 是 Python 2 和 3 之间的区别。显然,鉴于 OP 并没有说他们使用的是哪个,这是任何人的猜测...... @David Schwartz 我已经测试了 test_sum,它没有引起任何问题,实际上它是一个 c++ 函数,使用 python 编译为 so 文件,我已经在 shell 中对其进行了测试,它工作得很好跨度> 如果它没有引起问题,那么它不应该是minimal reproducible example的一部分;这是我们必须克服的分心 @David 我查看了您的答案并尝试返回 0 而不是 test_sum(l),但错误仍然存​​在....您能告诉我您究竟是如何忽略 test_sum 的吗? @DeepanshNagaria 我就是这样做的。我让它返回一个常量,并删除了import 语句。但是你需要问一个新问题。如果您可以在没有test_sum 的情况下复制错误,那么您为什么首先将其包含在您的问题中?您需要询问是什么导致了您的问题,否则我们不知道该看什么。继续删除内容,直到您有 非常 只包含导致问题的简单代码,或者您确定导致问题的一个特定内容并删除其他所有内容。

以上是关于正确编译的代码(没有错误)给出分段错误核心转储的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的代码中出现分段错误(核心转储)错误?

为啥我的代码结果显示分段错误(核心转储)?

为啥在编译我的代码C(linux)时出现分段错误(核心转储)[关闭]

什么原因导致C中出现分段错误(核心转储)?

运行我的代码时出现分段错误(核心转储)问题

在我的模板类示例中,出现“分段错误(核心转储)”错误