114#include <sys/syscall.h>
122static int pageSize=4096;
132static void segv_handler(
int sig, siginfo_t *sip,
void *xxx) {
135 int actionBeforeExit=0;
136 switch(sip->si_signo){
138 switch(sip->si_code){
140 errStr=
"SIGILL: Illegal opcode";
143 errStr=
"SIGILL: Illegal operand";
146 errStr=
"SIGILL: Illegal addressing mode";
149 errStr=
"SIGILL: Illegal trap";
152 errStr=
"SIGILL: Privileged opcode";
155 errStr=
"SIGILL: Privileged register";
158 errStr=
"SIGILL: Coprocessor error";
161 errStr=
"SIGILL: Internal stack error";
164 errStr=
"SIGILL: Unknown signal code";
168 switch(sip->si_code){
170 errStr=
"SIGFPE: Integer divide-by-zero";
173 errStr=
"SIGFPE: Integer overflow";
176 errStr=
"SIGFPE: Floating point divide-by-zero";
179 errStr=
"SIGFPE: Floating point overflow";
182 errStr=
"SIGFPE: Floating point underflow";
185 errStr=
"SIGFPE: Floating point inexact result";
188 errStr=
"SIGFPE: Invalid floating point operation";
191 errStr=
"SIGFPE: Subscript out of range";
194 errStr=
"SIGFPE: Unknown signal code";
198 switch(sip->si_code){
200 errStr=
"SIGSEGV: Address not mapped";
201 actionBeforeExit = 1;
204 errStr=
"SIGSEGV: Invalid permissions";
205 actionBeforeExit = -1;
208 errStr=
"SIGSEGV: Unknown signal code";
212 switch(sip->si_code){
214 errStr=
"SIGBUS: Invalid address alignment";
217 errStr=
"SIGBUS: Non-existent physical address";
220 errStr=
"SIGBUS: Object-specific hardware error";
223 errStr=
"SIGBUS: Unknown signal code";
227 errStr=
"Unknown signal";
230 vadr = (caddr_t)sip->si_addr;
231 fprintf(stderr,
"\n***** PID: %ld, Addr: %p, signal %s (code %d)\n",
232 (
long)getpid(), vadr, errStr,sip->si_code);
238 volatile int loopForever=1;
239 size_t alignedAdr=((size_t)vadr) & (~(pageSize-1));
240 fprintf(stderr,
" Attach gdb -p %ld and set var loopForever=0 in a corresponding frame",
245 fprintf(stderr,
"\n of a thread with LPW id %ld",(
long)syscall(SYS_gettid));
248 fprintf(stderr,
"\n of thread with LPW id %ld",(
long)gettid());
252 fprintf(stderr,
" to continue\n");
258 if(actionBeforeExit<0)
259 mprotect((
char*)alignedAdr, pageSize, PROT_READ | PROT_WRITE);
260 if(actionBeforeExit>0)
262 mmap((
void*)alignedAdr,pageSize,PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, 0, 0);
274static FORM_INLINE
int mprotectInit(
void)
277 pageSize = getpagesize();
278 sa.sa_sigaction = &segv_handler;
280 sigemptyset(&sa.sa_mask);
281 sigaddset(&sa.sa_mask, SIGIO);
282 sigaddset(&sa.sa_mask, SIGALRM);
284 sa.sa_flags = SA_SIGINFO;
286 if (sigaction(SIGILL, &sa, NULL)) {
287 fprintf(stderr,
"Error on assigning %s.\n",
"SIGILL");
290 if (sigaction(SIGFPE, &sa, NULL)) {
291 fprintf(stderr,
"Error on assigning %s.\n",
"SIGFPE");
294 if (sigaction(SIGSEGV, &sa, NULL)) {
295 fprintf(stderr,
"Error on assigning %s.\n",
"SIGSEGV");
298 if (sigaction(SIGBUS, &sa, NULL)) {
299 fprintf(stderr,
"Error on assigning %s.\n",
"SIGBUS");
314static void *mprotectMalloc(
size_t theSize)
324 size_t requestedSize=theSize;
334 if(theSize % pageSize)
336 theSize= (theSize/pageSize+nPages)*pageSize;
339 ret=(
char*)mmap(0,theSize,PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, 0, 0);
340 if(ret == MAP_FAILED)
344 if(mprotect(ret, pageSize, PROT_NONE))
return NULL;
348 if(mprotect(ret+(theSize-pageSize), pageSize, PROT_NONE))
return NULL;
359 return ret+ (theSize-pageSize-requestedSize);
370static void mprotectFree(
char *ptr)
373 if(ptr==NULL)
return;
377 size_t alignedPtr=((size_t)ptr) & (~(pageSize-1));
378 ptr=(
char*)alignedPtr;
383 mprotect(ptr, pageSize, PROT_READ);
384 theSize=*((
size_t*)ptr);