0

我有以下在线课程的作业,想知道是否有人熟悉偏执数组,因为很难获得这个特定课程的帮助。

您的 paranoid 数组将公开 parray.h 中提供的一个非常简单的接口。你可以假设 parray 不会被释放。parray new 调用创建了一个具有固定大小(size 参数)的一组条目(count 参数)的数组。在内部,数组不会在内存中连续排列元素,因此数组入口函数返回一个指向给定入口的指针(由参数索引指定)。为了在元素内溢出时触发段错误,您应该使用保护页。保护页的主要目的是在访问时触发段错误。因此,对保护表的页表读取、写入和执行权限被禁用,因此任何对该页的访问都会触发故障。当保护页紧跟在缓冲区或数据结构之后时,

数组中的每个条目都应由每一侧的保护页限定。例如,一个有 10 个条目的数组应该使用 11 个保护页:一个在第一个条目之前,一个在最后一个条目之后,九个在连续条目之间。

我的 parray_new 和 parray_entry 调用如下:

 typedef char byte;

 parray_t* parray_new(int size, int count)
 {
   struct parray* p = NULL;
   // TODO: Allocate and return parray
   // Add guard pages first at this time
   int pagesize = getpagesize();
 p->size = (size * count) + (pagesize * count) + pagesize;
 p->array = malloc(p->size + pagesize - 1);
 if(posix_memalign(&p->array, p->size, count))
 {
    exit(0);
 }

 return p;
 }

 void* parray_entry(struct parray* p, int index)
 {
   //int pagesize = getpagesize();
   byte* entry = NULL;
   // TODO: compute correct entry
   if (mprotect(&p->array, p->size-1, PROT_READ))
  {
         exit(0);
  }
   if (mprotect(&p->array, p->size, PROT_WRITE))
  {
     exit(0);
  }
   entry = (void*)(p->array + index); 
   return entry;
 }

我还有以下处理程序:

 static void handler(int sig, siginfo_t *si, void* unused)
 {
 // TODO: Use fprintf or perror to print 
 // a message indicating a segmentation fault
 // happened and provide the memory address
 // where the fault happened
 fprintf(stderr, "Segmentation Fault\n k = %d, %p\n", sig, si >si_addr);
 }

最后,主要方法:

 int main(void)
 {
    struct sigaction sa;
    /*
    * TODO: Overwrite the signal handler for 
    * SIGSEGV
    */
    memset(&sa, '\0', sizeof(sa));
    sa.sa_flags = SA_SIGINFO;
    sa.sa_sigaction = handler;
    if (sigaction(SIGSEGV, &sa, NULL) == -1)
    {
       perror("sigaction");
       exit(EXIT_FAILURE);
    }   
 }

在 main 方法中还有几个测试要运行,但我把这些都省略了,因为我在到达它们之前就遇到了错误。发生的情况是,处理程序永远打印(分段错误,k = 11, 0x8)。我不知道 11 或 0x8 的意义,但它不会停止打印该序列,直到我强制它。

任何帮助将不胜感激,对于这篇文章的长度,我深表歉意。谢谢

编辑:据我所知,处理程序继续打印。并不是我遇到了段错误(我可能是),但是无论我在处理程序中放入什么,它都会继续打印。另外,如果我将其更改为 perror 它也会这样做。我该怎么做才能让程序在处理程序之后继续?

4

0 回答 0