2013-07-02 49 views
3

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

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

+1

你是一个Linux的伊恩或Windows的伊恩?我的答案是Linux/gcc的定位,但可以很容易地适应,可能通过使用像“SetUnhandledExceptionFilter()”,与“EXCEPTION_ACCESS_VIOLATION”... –

+0

跨平台解决方案实际上 – user232343

+1

这可能是有用的,然后:http://旋.getomicobject.com/2013/01/13/exceptions-stack-traces-c /,具有“__WIN32”宏使用情况... –

回答

6

简单例子,可以帮助(使用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") 

输出继电器

hello1!正在生成段错误...

抓到SIGSEGV:segfault !!

hello2!运行安全代码...

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