You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Cython public函数被C代码调用时触发Segmentation fault段错误

问题根因

触发段错误的核心原因是C扩展模块初始化流程不完整:你仅调用了PyInit_public()创建模块对象,但没有将模块注册到Python运行时的模块表中,Cython生成的Qu()函数执行时依赖模块初始化阶段填充的全局上下文指针,上下文为空时直接访问空指针就会触发段错误。

另外两个隐藏的编译配置问题:

  • 调用cython生成C代码时没有显式指定language_level,默认值可能和你pxd里声明的Python3规则不匹配,埋下兼容隐患
  • GCC链接参数不全,没有加--embed参数拉取Python嵌入场景的完整链接选项,换个环境可能直接链接失败

修正方案

1. 修正C侧调用代码(public_c.c)

补全模块注册逻辑,增加初始化失败的基础判断:

#include <Python.h>
#include "public.h"

int main() {
    Py_Initialize();

    // 初始化模块后必须注册到sys.modules,才会触发模块完整的初始化逻辑
    PyObject* public_mod = PyInit_public();
    if (!public_mod) {
        if (PyErr_Occurred()) PyErr_Print();
        Py_Finalize();
        return 1;
    }
    PyDict_SetItemString(PyImport_GetModuleDict(), "public", public_mod);
    Py_DECREF(public_mod);

    printf("Init\n");
    Qu();
    printf("Finalize\n");

    Py_Finalize();
    return 0;
}

2. 修正编译脚本(compile.sh)

显式指定Cython的语言版本,调整链接参数:

#!/bin/bash
# 显式指定Python3语法,避免默认值兼容问题
cython -3 public.pyx
gcc -fPIC $(python3-config --cflags) -c public.c -o public.o
gcc -fPIC $(python3-config --cflags) -c public_c.c -o public_c.o
# 加--embed参数获取嵌入场景的完整链接选项,顺序符合GCC从左到右解析依赖的规则
gcc public_c.o public.o $(python3-config --embed --ldflags) -o public_c

验证结果

重新执行编译脚本后运行生成的public_c可执行文件,会按顺序输出如下内容,无段错误:

Init
Qu!
Finalize

补充说明:如果你的Cython版本较老,可能需要在调用Qu()前额外执行一次PyImport_ImportModule("public")确保模块级代码执行完毕,新版本Cython在模块注册到sys.modules时就会自动完成这部分逻辑。

内容的提问来源于stack exchange,提问作者m0Ray

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 00:42:22