print the segmentation fault reason
This question already has an answer here:
If you want to know the cause you can register a signal handler, something like:
void handler(int signum, siginfo_t *info, void *context)
{
struct sigaction action = {
.sa_handler = SIG_DFL,
.sa_sigaction = NULL,
.sa_mask = 0,
.sa_flags = 0,
.sa_restorer = NULL
};
fprintf(stderr, "Fault address: %pn", info->si_addr);
switch (info->si_code) {
case SEGV_MAPERR:
fprintf(stderr, "Address not mapped.n");
break;
case SEGV_ACCERR:
fprintf(stderr, "Access to this address is not allowed.n");
break;
default:
fprintf(stderr, "Unknown reason.n");
break;
}
/* unregister and let the default action occur */
sigaction(SIGSEGV, &action, NULL);
}
And then somewhere you need to register it:
struct sigaction action = {
.sa_handler = NULL,
.sa_sigaction = handler,
.sa_mask = 0,
.sa_flags = SA_SIGINFO,
.sa_restorer = NULL
};
if (sigaction(SIGSEGV, &action, NULL) < 0) {
perror("sigaction");
}
Basically you register a signal that fires when SIGSEGV is delivered, and you get some additional info, to quote the man page:
The following values can be placed in si_code for a SIGSEGV signal:
SEGV_MAPERR address not mapped to object
SEGV_ACCERR invalid permissions for mapped object
These map to the two basic reasons for getting a seg fault -- either the page you accessed wasn't mapped at all, or you weren't allowed to perform whatever operation you attempted to that page.
Here after the signal handler fires it unregisters itself and replaces the default action. This causes the operation that failed to be performed again so it can be caught by the normal route. This is the normal behavior of a page fault (the precursor to getting a seg fault) so that things like demand paging work.
As already answered here: How to generate a stacktrace when my gcc C++ app crashes
You can (in the case of GCC with Linux/BSD at least) do this fairly easy:
Example code:
#include <stdio.h>
#include <execinfo.h>
#include <signal.h>
#include <stdlib.h>
void handler(int sig) {
void *array[10];
size_t size;
// get void*'s for all entries on the stack
size = backtrace(array, 10);
// print out all the frames to stderr
fprintf(stderr, "Error: signal %d:n", sig);
backtrace_symbols_fd(array, size, 2);
exit(1);
}
int main(int argc, char **argv) {
signal(SIGSEGV, handler); // install our handler
char * ptr = NULL;
*ptr = "hello"; /* this will cause a segmentation fault */
}
Example output:
# gcc -g -rdynamic -o test test.c
# ./test
Error: signal 11:
0 test 0x000000010e99dcfa handler + 42
1 libsystem_c.dylib 0x00007fff95c1194a _sigtramp + 26
2 ??? 0x0000000000000000 0x0 + 0
3 libdyld.dylib 0x00007fff8fa177e1 start + 0
4 ??? 0x0000000000000001 0x0 + 1
链接地址: http://www.djcxy.com/p/86040.html
上一篇: C ++显示堆栈跟踪异常
下一篇: 打印分段故障原因