segmentation fault(core dumped) in python with swig,但是当我更改变量名时它起作用

segmentation fault(core dumped) in python with swig, but it works when I change the variable name

我正在使用 python swig。 cpp 文件包含一个变量 int step=0; 和一个函数使用变量 void test(); 当我调用 python 中的函数时出现分段错误。 但是在我将变量名称更改为 step2 后,它起作用了。

版本: 痛饮 4.0.0 python3.6.7

这会出现分段错误:

1.ex.cpp

#include<iostream>

int step = 0;

void test(){
    step += 1;
    printf("ok\n");
}

2.ex.i

%module ex

%inline %{
    extern void test();
%}

3.run

swig -c++ -python ex.i
g++ -fPIC -c ex.cpp -c ex_wrap.cxx -I/home/lzhang/venv/include/python3.6m
g++ -shared ex.o ex_wrap.o -o _ex.so

4.get 分段错误

$ python
Python 3.6.7 (default, Oct 22 2018, 11:32:17) 
[GCC 8.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import ex
>>> ex.test()
Segmentation fault (core dumped)

但是我只改了变量名:

#include<iostream>

int step2 = 0;

void test(){
    step2 += 1;
    printf("ok\n");
}

重新编译后就可以了

$ python
Python 3.6.7 (default, Oct 22 2018, 11:32:17) 
[GCC 8.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import ex
>>> ex.test()
ok
>>> 

如何避免这种错误?

你的问题的根源似乎是 step 是从 libc 导出的,至少在一堆常见的系统上是这样,所以你有一个全局命名空间冲突。

nm -D /lib/arm-linux-gnueabihf/libc-2.28.so|grep step
000c5210 W step

(这是一个函数,我有点好奇它的用途,因为它不是我熟悉的 - 事实证明它与正则表达式处理有关,并在字符串中查找已编译正则表达式的下一个匹配项缓冲区)

在您的特定示例中,最简单的解决方案是让您的全局变量 step 成为 static(或使用匿名命名空间):

#include<iostream>

static int step = 0;

void test(){
    step += 1;
    printf("ok\n");
}

这足以修复您的示例。

最好确保所有全局变量都是静态的,除非您真的想导出它们,尤其是在构建共享对象(例如 Python 模块)时。

您还可以使用 gcc 的 -fvisibility=hidden 默认隐藏而不是导出全局变量。 (SWIG 正确地确保需要导出的东西即使在设置时仍然可见)。