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

how to add signal handler as method

本文关键字:添加 方法 程序 信号处理      更新时间:2023-10-16

compile

# 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 %sn", i, messages[i]);
}

exit(1);
}
void baz(){
int *foo = (int*)-1;
printf("%dn", *foo);
}
void bar() { baz(); }
void foo() { bar(); }

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

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

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

typedef void (*sighandler_t)(int);

您的类型是:

void (Backtrace::*)(int);

您将需要以下任一:

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

类似的例子可以在这里找到。

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

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

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