Bug in JIAJIA

来源:互联网 发布:php众筹源码 编辑:程序博客网 时间:2024/06/04 23:34

JIAJIA can not catch the fault address correctly in sigsevg_handler for x86_64

http://us.generation-nt.com/answer/sigsegv-signal-handler-help-183484481.html

http://comp.os.linux.development.apps.narkive.com/wH6d4yNJ/fail-to-get-the-fault-address-from-sigcontext-cr2

http://sourceware.org/ml/libc-help/2009-10/msg00021.html
http://comp.os.linux.development.apps.narkive.com/wH6d4yNJ/fail-to-get-the-fault-address-from-sigcontext-cr2

In JIAJIA/src/mem.c line 462


In 32-bit system, sigctx_cr2 record the fault address 200000, but not in 64-bit.

sigsegv.c

#include <time.h>#include <stdio.h>#include <sys/time.h>#include <signal.h>#include <string.h>void my_sigsegv(int signo, struct sigcontext sigctx){    printf("Produce sigsegv %d\n",signo);    printf("%ld:\n",sigctx.cr2);    return ;}int main(){    struct sigaction act;    act.sa_handler =  my_sigsegv ;    sigemptyset(&act.sa_mask);    act.sa_flags = 0;    sigaction(SIGSEGV , &act , NULL);    char *pstr = 200000;    strcpy(pstr , "hello");}


Solution (man sigaction for details)

In mem.c line 170#ifdef LINUX    jiamapfd=open("/dev/zero", O_RDWR,0);    {         /*struct sigaction act;          act.sa_handler = (void_func_handler)sigsegv_handler;          sigemptyset(&act.sa_mask);          act.sa_flags = SA_NOMASK;          if (sigaction(SIGSEGV, &act, NULL))          assert0(0,"segv sigaction problem");*/        //xiao        struct sigaction act;        // act.sa_handler = (void_func_handler)sigsegv_handler;        act.sa_sigaction = sigsegv_handler;        sigemptyset(&act.sa_mask);        // act.sa_flags = SA_NOMASK;        act.sa_flags = SA_NOMASK | SA_SIGINFO;        if (sigaction(SIGSEGV, &act, NULL))            assert0(0,"segv sigaction problem");    }

In mem.c line 481

#ifdef LINUX    //void sigsegv_handler(int signo, struct sigcontext sigctx)    //xiao_bug    //void sigsegv_handler( int sig, siginfo_t *sip,struct sigcontext *scp)    //xiao_bug:void sigsegv_handler (int signo, struct siginfo *info, void *data)    //http://comp.os.linux.development.apps.narkive.com/wH6d4yNJ/fail-to-get-the-fault-address-from-sigcontext-cr2#endif 

In mem.c line 75

#ifdef LINUX //void sigsegv_handler(int, struct sigcontext);//xiao//void sigsegv_handler( int sig, siginfo_t *sip,struct sigcontext *scp);//xiaovoid sigsegv_handler (int signo, struct siginfo *info, void *data);#endif

In mem.c line 526

#ifdef LINUX    /*faultaddr = (address_t) sigctx.cr2;      faultaddr = (address_t) ((unsigned long) faultaddr/Pagesize*Pagesize);      writefault = (int) sigctx.err & 2;*/    //xiao    DPRINTF("Come to linux\n");    DPRINTF("errno:%d code:%d addr:0x%x\n",info->si_errno,info->si_code,info->si_addr);    faultaddr = (address_t)info->si_addr;    DPRINTF("faultaddr=%lx\n",(long)faultaddr);    faultaddr = (address_t) ((unsigned long) faultaddr/Pagesize*Pagesize);    //how to get the writfualt    //writefault = (int) info->si_errno & 2;#endif 


access type (READ or WRITE) during SEGV 

http://computer-programming-forum.com/46-asm/81c68464056ab13a.htm

In /usr/include/x86_64-linux-gnu/sys/ucontext.h  40 line (For user space to use the register)

//xiao#ifndef __USE_GNU#define __USE_GNU#endif

#include <time.h>    #include <stdio.h>    #include <sys/time.h>    #include <signal.h>    #include <string.h>    #include <sys/ucontext.h>    void my_sigsegv(int signo, struct siginfo * info, void * data)    {        printf("Produce sigsegv %d\n",signo);        printf("%ld\n",(long)info->si_addr);      struct ucontext *ucp = (struct ucontext *)data;      printf("REG_ERR:%d\n",ucp->uc_mcontext.gregs[REG_ERR]);      int type = ucp->uc_mcontext.gregs[REG_ERR] & 2;      printf("type=%d\n",type);      if(type == 2) {          printf("write\n");      }else {          printf("read\n");      }      return ;    }      int main()    {        struct sigaction act;        act.sa_sigaction =  my_sigsegv;        sigemptyset(&act.sa_mask);        act.sa_flags = SA_SIGINFO;        sigaction(SIGSEGV, &act, NULL);          char *pstr = 200000;       // *pstr = 31;   //   *pstr = 0;      printf("%c\n", *pstr);  //    strcpy(pstr,"hello");    }   


#include <time.h>      #include <stdio.h>      #include <sys/time.h>      #include <signal.h>      #include <string.h>      #include <sys/ucontext.h>  #include <sys/mman.h> #include <fcntl.h> long jiamapfd = 0; void my_sigsegv(int signo, struct siginfo * info, void * data)      {          printf("Produce sigsegv %d\n",signo);          printf("faultaddr:%lx\n",(long)info->si_addr);        long faultaddr = (long)info->si_addr;     struct ucontext *ucp = (struct ucontext *)data;       // printf("REG_ERR:%d\n",ucp->uc_mcontext.gregs[REG_ERR]);        int type = ucp->uc_mcontext.gregs[REG_ERR] & 2;        type = (type==0)?0:1;     if(type == 1) {            printf("write fault\n");        }else {            printf("read fault\n");        }        long  mapad= (long)mmap(faultaddr,8192,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_FIXED,jiamapfd,0);     printf("Map:0x%lx\n",mapad);     return ;      }       int main()      {          struct sigaction act;          act.sa_sigaction =  my_sigsegv;          sigemptyset(&act.sa_mask);          act.sa_flags = SA_SIGINFO;          sigaction(SIGSEGV, &act, NULL);          jiamapfd = open("/dev/zero",O_RDWR,0);    char * p = 0x70000000;    *p = *p + 3;    printf("%c\n",*p);    char *s = 0x70003000;    *s = 5; }

Produce sigsegv 11faultaddr:70000000read faultMap:0x70000000Produce sigsegv 11faultaddr:70003000write faultMap:0x70003000


原创粉丝点击