cython segmentation fault handling

前端 未结 1 1303
傲寒
傲寒 2021-01-20 03:55

I am wrapping some C library, and I have one function which in some cases may result with segmentation fault. In that case I need to call second function, which will in that

1条回答
  •  栀梦
    栀梦 (楼主)
    2021-01-20 04:39

    A short example that might help (using signal):

    example.h (assuming the Cython extension is named 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 
    #include 
    
    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")
    

    Ouput

    hello1 ! Generating segfault...

    Caught SIGSEGV: segfault !!

    hello2 ! Running safe code...

    I hope this gives some ideas, at least...

    0 讨论(0)
提交回复
热议问题