使用 swig 在 Python 中分段错误(核心转储),但当我更改变量名称时它可以工作

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

本文关键字:改变 变量名 工作 Python swig 分段 错误 转储 核心 使用      更新时间:2023-10-16

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

版本: SWIG 4.0.0 蟒蛇 3.6.7

这会得到一个分段错误:

1.例如.cpp

#include<iostream>
int step = 0;
void test(){
step += 1;
printf("okn");
}

2.例

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

3.运行

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.获取分段错误

$ 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("okn");
}

重新编译后,它可以工作。

$ 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

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

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

#include<iostream>
static int step = 0;
void test(){
step += 1;
printf("okn");
}

这足以修复您的示例。

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

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