2013-07-02 82 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!運行安全代碼...

我希望這給一些想法,至少...