不知道为什么在linux系统内无法捕获SIGSEGV信号。但是控制台已经报出了Segmentation fault (core dumped)
。下面是代码和控制台信息。 我的目的是要在代码中捕获SIGSEGV信号。我只是想知道我为什么无法从代码中捕获SIGSEGV信号。以及我如何才能够在代码中捕获如下的SIGSEGV信号。
#include <cstring>
#include "threadTest.hpp"
#include "iostream"
#include "pthread.h" //线程 锁
#include "unistd.h" //睡眠
#include "semaphore.h"//信号量
#include "signal.h"
#include "errno.h"
#include "stdlib.h"
struct BigObj {
char* a1="a";
char* a2="a";
char* a3="a";
char* a4="a";
char* a5="a";
char* a6="a";
char* a7="a";
char* a8="a";
char* a9="a";
char* a10="a";
char* a11="a";
char* a12="a";
char* a13="a";
char* a14="a";
char* a15="a";
char* a16="a";
char* a17="a";
char* a18="a";
char* a19="a";
char* a20="a";
char* a21="a";
char* a22="a";
char* a23="a";
char* a24="a";
char* a25="a";
char* a26="a";
char* a27="a";
char* a28="a";
char* a29="a";
char* a30="a";
char* a31="a";
char* a32="a";
char* a33="a";
char* a34="a";
char* a35="a";
char* a36="a";
char* a37="a";
char* a38="a";
char* a39="a";
char* a40="a";
char* a41="a";
char* a42="a";
char* a43="a";
char* a44="a";
char* a45="a";
char* a46="a";
char* a47="a";
char* a48="a";
char* a49="a";
char* a50="a";
char* a51="a";
char* a52="a";
char* a53="a";
char* a54="a";
char* a55="a";
char* a56="a";
char* a57="a";
char* a58="a";
char* a59="a";
char* a60="a";
char* a61="a";
char* a62="a";
char* a63="a";
char* a64="a";
char* a65="a";
char* a66="a";
char* a67="a";
char* a68="a";
char* a69="a";
char* a70="a";
char* a71="a";
char* a72="a";
};
static void add_error_signals_to_set(sigset_t* set) {
sigaddset(set, SIGILL);
sigaddset(set, SIGBUS);
sigaddset(set, SIGFPE);
sigaddset(set, SIGSEGV);
sigaddset(set, SIGTRAP);
}
static void remove_error_signals_from_set(sigset_t* set) {
sigdelset(set, SIGILL);
sigdelset(set, SIGBUS);
sigdelset(set, SIGFPE);
sigdelset(set, SIGSEGV);
sigdelset(set, SIGTRAP);
}
static unsigned int index_t = 0;
static void* stack;
void signal_SIGSEGV_handler(int sig) {
void *frame_addr = __builtin_frame_address(0);
printf("Got tid=%p SIGSEGV at address: 0x%lx\n", pthread_self(), frame_addr);
exit(EXIT_FAILURE);
}
void signal_SIGBUS_handler(int sig) {
void *frame_addr = __builtin_frame_address(0);
printf("Got pid=%p SIGBUS at address: 0x%lx\n", pthread_self(), frame_addr);
exit(EXIT_FAILURE);
}
void signal_SIGABRT_handler(int sig) {
void *frame_addr = __builtin_frame_address(0);
printf("Got pid=%p SIGABRT at address: 0x%lx\n", pthread_self(), frame_addr);
exit(EXIT_FAILURE);
}
void signal_SIGIO_handler(int sig) {
void *frame_addr = __builtin_frame_address(0);
printf("Got pid=%p SIGIO at address: 0x%lx\n", pthread_self(), frame_addr);
exit(EXIT_FAILURE);
}
void signal_SIGCHLD_handler(int sig) {
void *frame_addr = __builtin_frame_address(0);
printf("Got pid=%p SIGCHLD at address: 0x%lx\n", pthread_self(), frame_addr);
exit(EXIT_FAILURE);
}
static void javaSignalHandler(int sig, siginfo_t* info, void* ucVoid) {
void *frame_addr = __builtin_frame_address(0);
printf("Got pid=%p javaSignalHandler at address: 0x%lx\n", pthread_self(), frame_addr);
exit(EXIT_FAILURE);
}
void set_signal_handler(int sig, bool do_check = true) {
struct sigaction oldAct;
sigaction(sig, (struct sigaction*)NULL, &oldAct);
struct sigaction sigAct;
sigfillset(&(sigAct.sa_mask));
remove_error_signals_from_set(&(sigAct.sa_mask));
sigAct.sa_sigaction = javaSignalHandler;
sigAct.sa_flags = SA_SIGINFO|SA_RESTART;
int ret = sigaction(sig, &sigAct, &oldAct);
printf("ERROR ret:%d\n", ret);
}
#include "alloca.h"
typedef unsigned char* address;
void *thread_function(void *arg) {
void *frame_addr = __builtin_frame_address(0); //获取当前线程栈帧的 起始地址
printf("sizeof(BigObj):%d\n", sizeof(BigObj));
printf("stack_address:%p\n", frame_addr);
pthread_t cur_id = pthread_self();
pthread_attr_t attr;
address* bottom;
void* stack;
size_t* size;
size_t guard_size;
int rslt = pthread_getattr_np(pthread_self(), &attr);
if(rslt != 0) {
printf("ERROR:%d\n", rslt);
exit(EXIT_FAILURE);
}
pthread_attr_getguardsize(&attr, &guard_size);
size_t stack_size;
pthread_attr_getstacksize(&attr, &stack_size);
char a[stack_size-10240];
size_t size1 = (size_t)((char*)(frame_addr) - (char*)(&a[index_t]));
BigObj a1;
BigObj a2;
BigObj a3;
BigObj a4;
BigObj a5;
BigObj a6;
BigObj a7;
BigObj a8;
BigObj a9;
BigObj a10;
BigObj a11;
BigObj a12;
BigObj a13;
BigObj a14;
while (true) {
if(index_t%100 == 0) {
printf("[%d] access address1: %p sizeof:%ld \n", index_t, &a[index_t]);
}
a[index_t] = 'a';
index_t+=1;
}
}
#define PAGE_SIZE 4096
#define STK_SIZE (10 * PAGE_SIZE)
void guard_size_thread() {
//线程的guard区域同样是PROT_NONE的,如果访问这段内存,同样会使系统内核发出SIGSEGV信号
signal(SIGBUS, signal_SIGBUS_handler);
// signal(SIGSEGV, signal_SIGSEGV_handler);
set_signal_handler(SIGSEGV);
signal(SIGABRT, signal_SIGABRT_handler);
signal(SIGIO, signal_SIGIO_handler);
signal(SIGCHLD, signal_SIGCHLD_handler);
// signal(SIGABRT, signal_SIGABRT_handler);
size_t pagesize = sysconf(_SC_PAGESIZE);
size_t guardsize = pagesize;
size_t stacksize = pagesize * 8192;
printf("pagesize:%d\n", pagesize);
printf("sizeof(char):%d\n", sizeof(char));
pthread_attr_t attr_t;
pthread_t tid;
pthread_attr_init(&attr_t);
// pthread_attr_setstacksize(&attr_t, stacksize);
// int ret = pthread_attr_setguardsize(&attr_t, 0);
// printf("ret=%d\n", ret);
// posix_memalign(&stack,PAGE_SIZE,STK_SIZE);
// pthread_attr_setstack(&attr_t, stack, PAGE_SIZE);
// int c;
// std::cin >> c;
pthread_create(&tid, &attr_t, thread_function, NULL);
pthread_attr_getguardsize(&attr_t, &guardsize);
pthread_attr_getstacksize(&attr_t, &stacksize);
printf("tid=%p guardsize:%d stacksize:%d\n", pthread_self(), guardsize, stacksize);
pthread_join(tid, NULL);
}
int main(){
guard_size_thread();
}
rockjiang@rockjiang-virtual-machine:~/CLionProjects/test/cmake-build-debug$ ./test
pagesize:4096
sizeof(char):1
tid=0x7fbc53ccf3c0 guardsize:4096 stacksize:8388608
ERROR ret:0
sizeof(BigObj):576
stack_address:0x7fbc53ccae50
Segmentation fault (core dumped)
rockjiang@rockjiang-virtual-machine:~/CLionProjects/test/cmake-build-debug$ ^C