如何将信号处理程序添加为方法

时间:2018-06-21 14:28:36

标签: c++

编译

# g++ -rdynamic ./test_stacktrace.cpp -o test_stacktrace
./test_stacktrace.cpp: In function ‘int main(int, char**)’:
./test_stacktrace.cpp:63:25: error: invalid use of non-static member function
  signal(SIGSEGV, b.trace);

代码

/*
 *  g++ -rdynamic ./test_stacktrace.cpp -o test_stacktrace
*/

#include <stdio.h>
#include <execinfo.h>
#include <signal.h>
#include <stdlib.h>

class Backtrace {
    public:
        Backtrace();
        void trace(int sig);
};

Backtrace::Backtrace(){}

void Backtrace::trace(int sig){
    void *trace[10];
    char **messages = (char **)NULL;
    int i, trace_size = 0;

    trace_size = backtrace(trace, 10);
    messages = backtrace_symbols(trace, trace_size);

    fprintf(stderr, "Error: signal %d:\n", sig);
    for(i=1; i<trace_size; ++i){
        fprintf(stderr, "#%d %s\n", i, messages[i]);
    }

    exit(1);
}

void baz(){
    int *foo = (int*)-1;
    printf("%d\n", *foo);
}

void bar() { baz(); }
void foo() { bar(); }


int main(int argc, char **argv){
    Backtrace b;

    signal(SIGSEGV, b.trace);
    foo();
}

2 个答案:

答案 0 :(得分:4)

您无法添加成员函数,signal函数无法绑定对象b。函数指针必须遵循以下格式:

typedef void (*sighandler_t)(int);

您的类型是:

void (Backtrace::*)(int);

您将需要:

  1. 要添加为信号处理程序的类Backtrace的全局函数和全局实例。
  2. Backtrace的静态成员函数和静态实例。

类似的例子can be found here.

但是,看起来您的示例实际上并不需要一个类。您没有成员变量。您可以将trace用作免费功能来实现所需的功能。

答案 1 :(得分:0)

如果定义Backtrace的全局实例,则可以在普通函数中使用它,也可以将Lambda表达式强制转换为正确的类型:

Backtrace b;

void bTrace(int s) { b.trace(s); }

int main() {
    signal(SIGSEGV, &bTrace);
    signal(SIGKILL, [](int s){ b.trace(s); });
}