【问题标题】:how to add signal handler as method如何将信号处理程序添加为方法
【发布时间】:2018-06-21 14:28:36
【问题描述】:

编译

# 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();
}

【问题讨论】:

    标签: c++


    【解决方案1】:

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

    typedef void (*sighandler_t)(int);
    

    你的类型是::

    void (Backtrace::*)(int);
    

    您将需要一个:

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

    类似例子can be found here.

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

    【讨论】:

    • @clarkk 是的,答案列出了 2。链接另一个具有类似 2 的答案。
    • @clarkk 再看一遍,您实际上似乎并不需要一个类,只需将其设为免费函数即可。
    【解决方案2】:

    如果你定义了一个Backtrace 的全局实例,你可以在一个普通函数中使用它,或者一个可以强制转换为正确类型的 lambda 表达式:

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

    【讨论】:

    • Backtrace b; void bTrace(int sig){ b.trace(int sig); } int main(int argc, char **argv){ signal(SIGSEGV, &amp;bTrace); foo(); }
    • 返回此错误./test_stacktrace.cpp: In function ‘void bTrace(int)’: ./test_stacktrace.cpp:38:10: error: expected primary-expression before ‘int’ b.trace(int sig);
    • 是的,我在 lambda 中命名了参数,但在全局函数中忘记了。查看我编辑的帖子。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-07
    相关资源
    最近更新 更多