正确编译的代码(没有错误)给出分段错误核心转储
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
的情况下复制错误,那么您为什么首先将其包含在您的问题中?您需要仅询问是什么导致了您的问题,否则我们不知道该看什么。继续删除内容,直到您有 非常 只包含导致问题的简单代码,或者您确定导致问题的一个特定内容并删除其他所有内容。以上是关于正确编译的代码(没有错误)给出分段错误核心转储的主要内容,如果未能解决你的问题,请参考以下文章