信号处理程序中的回溯
Backtrace inside Signal Handler
我正在尝试按照 this post 中的代码让信号处理程序打印有关浮点和分段错误等错误的回溯。我使用段故障信号作为起点。这是代码:
#include <cstdlib> //for exit()
#include <signal.h> //signal handling
#include <execinfo.h> //backtrace, backtrace_symbols and backtrace_fd
#include <iostream>
#include <string.h>
#include <stdio.h>
#define TRACE_MSG fprintf(stderr, "TRACE at: %s() [%s:%d]\n", \
__FUNCTION__, __FILE__, __LINE__)
void show_stackframe()
{
void *trace[1024];
char **messages = (char **) NULL;
int i, trace_size = 0;
TRACE_MSG;
trace_size = backtrace(trace, 1024); // segfault here???
// More code here to print backtrace, but not needed at the moment..
TRACE_MSG;
}
void sigSegvHandler( int signum, siginfo_t* info, void* arg )
{
TRACE_MSG;
show_stackframe();
return;
}
double func_b()
{
show_stackframe(); // Show that backtrace works without being
// called inside sighandler.
TRACE_MSG;
int int_a[5];
int_a[0] = 4;
int_a[11] = 10; // cause a segfault on purpose to see
// how the signal handling performs.
return 1.1;
}
int main()
{
// Examine and change the seg fault signal
struct sigaction segvAction; // File: /usr/include/bits/sigaction.h
// Initialize segvAction struct to all zeros for initialiation
memset( &segvAction, 0, sizeof( segvAction ) );
segvAction.sa_sigaction = sigSegvHandler;
segvAction.sa_flags = SA_SIGINFO; //Invoke signal catching function with 3 arguments instead of 1
// Set the action for the SIGSEGV signal
sigaction( SIGSEGV, &segvAction, NULL );
func_b(); // Produce a SIGSEGV error
}
我正在编译使用:
g++ -rdynamic testprogram.cpp -o testprogram
我从程序中收到以下输出:
TRACE at: show_stackframe() [Whosebug.cpp:15]
TRACE at: show_stackframe() [Whosebug.cpp:17]
TRACE at: func_b() [Whosebug.cpp:33]
TRACE at: sigSegvHandler() [Whosebug.cpp:22]
TRACE at: show_stackframe() [Whosebug.cpp:15]
Segmentation fault
我的问题是为什么 show_stackframe() 在 sigaction 内部导致分段错误,但在不在 sigaction 处理程序内部时工作正常?我显然似乎设置了信号 handler/action 不正确,但我一整天都找不到它。 GDB 在这种情况下似乎没有任何帮助。
如 here 所述,backtrace
函数是 AS-Unsafe,这意味着从异步信号处理程序调用是不安全的。这样做会调用未定义的行为。
我正在尝试按照 this post 中的代码让信号处理程序打印有关浮点和分段错误等错误的回溯。我使用段故障信号作为起点。这是代码:
#include <cstdlib> //for exit()
#include <signal.h> //signal handling
#include <execinfo.h> //backtrace, backtrace_symbols and backtrace_fd
#include <iostream>
#include <string.h>
#include <stdio.h>
#define TRACE_MSG fprintf(stderr, "TRACE at: %s() [%s:%d]\n", \
__FUNCTION__, __FILE__, __LINE__)
void show_stackframe()
{
void *trace[1024];
char **messages = (char **) NULL;
int i, trace_size = 0;
TRACE_MSG;
trace_size = backtrace(trace, 1024); // segfault here???
// More code here to print backtrace, but not needed at the moment..
TRACE_MSG;
}
void sigSegvHandler( int signum, siginfo_t* info, void* arg )
{
TRACE_MSG;
show_stackframe();
return;
}
double func_b()
{
show_stackframe(); // Show that backtrace works without being
// called inside sighandler.
TRACE_MSG;
int int_a[5];
int_a[0] = 4;
int_a[11] = 10; // cause a segfault on purpose to see
// how the signal handling performs.
return 1.1;
}
int main()
{
// Examine and change the seg fault signal
struct sigaction segvAction; // File: /usr/include/bits/sigaction.h
// Initialize segvAction struct to all zeros for initialiation
memset( &segvAction, 0, sizeof( segvAction ) );
segvAction.sa_sigaction = sigSegvHandler;
segvAction.sa_flags = SA_SIGINFO; //Invoke signal catching function with 3 arguments instead of 1
// Set the action for the SIGSEGV signal
sigaction( SIGSEGV, &segvAction, NULL );
func_b(); // Produce a SIGSEGV error
}
我正在编译使用:
g++ -rdynamic testprogram.cpp -o testprogram
我从程序中收到以下输出:
TRACE at: show_stackframe() [Whosebug.cpp:15]
TRACE at: show_stackframe() [Whosebug.cpp:17]
TRACE at: func_b() [Whosebug.cpp:33]
TRACE at: sigSegvHandler() [Whosebug.cpp:22]
TRACE at: show_stackframe() [Whosebug.cpp:15]
Segmentation fault
我的问题是为什么 show_stackframe() 在 sigaction 内部导致分段错误,但在不在 sigaction 处理程序内部时工作正常?我显然似乎设置了信号 handler/action 不正确,但我一整天都找不到它。 GDB 在这种情况下似乎没有任何帮助。
如 here 所述,backtrace
函数是 AS-Unsafe,这意味着从异步信号处理程序调用是不安全的。这样做会调用未定义的行为。