【问题标题】:cython segmentation fault handlingcython 分段错误处理
【发布时间】:2013-07-02 20:50:51
【问题描述】:

我正在包装一些 C 库,并且我有一个函数在某些情况下可能会导致分段错误。在这种情况下,我需要调用第二个函数,这将在这种情况下成功完成。

有谁知道如何处理 cython 中的分段错误?

【问题讨论】:

  • 你是 Linux 人还是 Windows 人?我在下面的回答是面向 Linux/gcc 的,但可以很容易地适应,可能通过使用“SetUnhandledExceptionFilter()”之类的东西,带有“EXCEPTION_ACCESS_VIOLATION”...
  • 其实是跨平台解决方案
  • 这可能很有用:spin.atomicobject.com/2013/01/13/exceptions-stack-traces-c,使用“__WIN32”宏...
  • 审阅:上面的例子完全兼容Windows/gcc (MinGW)...

标签: c exception-handling segmentation-fault cython


【解决方案1】:

一个可能有帮助的简短示例(使用signal):

example.h(假设 Cython 扩展名为 myext.pyx

// Header autogenerated by Cython when declaring "public api" functions
#include "../myext_api.h"  

void handleFuncFailure(char *func1_name, char *func2_name);
void generateSegFault();

example.c

#include <example.h>
#include <signal.h>

static char *func2name;

static void handler2(int sig)
{
    // Catch exceptions
    switch(sig)
    {
        case SIGSEGV:
            fputs("Caught SIGSEGV: segfault !!\n", stderr);
            break;
    }
    int error;
    // "call_a_cy_func()" is provided by "myext.pyx"
    call_a_cy_func(func2name, &error);
    exit(sig);
}

void handleFuncFailure(char *func1_name, char *func2_name) {

    // Provided by autogenerated "myext_api.h" header
    import_myext();

    func2name = func2_name;
    signal(SIGSEGV, handler2);
    int error;
    // "call_a_cy_func()" is provided by "myext.pyx"
    call_a_cy_func(func1_name, &error);
}

void generateSegFault() {
    *(int*) 0 = 0;
}

myext.pyx

# Helper function to call a function by its name
# "public api" enables to call this function from C side (See above)
cdef public api void call_a_cy_func(char* method, bint *error):
    if (method in globals()):
        error[0] = 0
        globals()[method]();
    else:
        error[0] = 1

# Expose C functions
cdef extern from "src/example.h":
    void handleFuncFailure(char *func1_name, char *func2_name)
    void generateSegFault()

# The unreliable function
def func1():
    print "hello1 ! Generating segfault..."
    generateSegFault()

# The reliable function
def func2():
    print "hello2 ! Running safe code..."

# To be called from the Cython extension inner code    
cdef myHandleFuncFailure(f1, f2):
    handleFuncFailure(f1, f2)

# To be called from Python source by importing "myext" module
def myHandleFuncFailure2():
    myHandleFuncFailure("func1", "func2")

输出

你好1!正在生成段错误...

捕获 SIGSEGV:segfault !

你好2!运行安全代码...

我希望这能给你一些想法,至少......

【讨论】:

    猜你喜欢
    • 2018-10-08
    • 2018-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-20
    • 1970-01-01
    相关资源
    最近更新 更多