segmentation fault due to initialize() function when changing the size of the huge page allocation

a 夏天 提交于 2020-01-06 12:44:23

问题


I encounter segmentation fault in my program when I play with the size of the memory that I want to allocate with huge page, i.e., when I define LENGTH = 4*1024, there is seg fault. When I define 4*1024*1024, there is no seg fault. What is the root cause of this?

Code below:

#define _POSIX_C_SOURCE 199309
#define _GNU_SOURCE
#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <time.h>
#include <string.h>
#include <errno.h>

#define PROTECTION (PROT_READ | PROT_WRITE)
#define LENGTH (4*1024)
//#define LENGTH (4*1024*1024)
#define LINE_SIZE 64
#define ASSOC 16
#define CACHE_SIZE (4*1024*1024)
#define WAY_SIZE (CACHE_SIZE/ASSOC)

#ifndef MAP_HUGETLB
#define MAP_HUGETLB 0x40000
#endif

#define ADDR (void *) (0x0UL)
#define FLAGS (MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB)

int main (int argc, char *argv[]){
...
  // allocate a buffer with the same size as the LLC using huge pages
  buf = mmap(ADDR, LENGTH, PROTECTION, FLAGS, 0, 0);
  if (buf == MAP_FAILED) {
    perror("mmap");
    exit(1);
  }
  set_S = atoi(argv[1]);
  set_M = atoi(argv[2]);
  printf("test 0\n");
  initialize(set_S);
  printf("test 1\n");
  initialize(set_M);
  printf("test 2\n");
  head_S = &buf[set_S*LINE_SIZE];
  printf("test 3\n");
  head_M = &buf[set_M*LINE_SIZE];

...
}

Note that there is no huge page on enabled by default in my computer, so I turned it on as root:

echo 20 > /proc/sys/vm/nr_hugepages

This is the huge page related info in /proc/meminfo after I turn on huge page:

HugePages_Total:      20
HugePages_Free:       20
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB

Program output:

$./a.out 1 1
test 0
Segmentation fault (core dumped)

$uname output:

Linux mymachine 3.13.0-43-generic #72-Ubuntu SMP Mon Dec 8 19:35:06 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux

EDIT 1: Add the initialize function:

void initialize(int set){
  int j, k;
  char ** ptr1, ** ptr2;
  char * tmp;

  // re-initialize pointer array of size "size"
  // implementation of Sattolo's random cyclic permutation
  for (j=0; j<ASSOC; j++){
    ptr1 = (char **)&buf[set*LINE_SIZE+j*WAY_SIZE];
    *ptr1 = (char*)ptr1;
  }

  // permute each set
  for (j=ASSOC-1; j>=1; j--){
    k = rand()%j;
    ptr1 = (char **)&buf[set*LINE_SIZE+j*WAY_SIZE];
    ptr2 = (char **)&buf[set*LINE_SIZE+k*WAY_SIZE];
    tmp = *ptr1;
    *ptr1 = *ptr2;
    *ptr2 = tmp;
  }
}

回答1:


When accessing set*LINE_SIZE+(ASSOC-1)*WAY_SIZE = set*64 + CACHE_SIZE - WAY_SIZE = set*64 + 4*1024*1024 - WAY_SIZE which is bigger than mmap length LENGTH = 4*1024 in the loop of initialize , you are accessing memory out of bound. That's the reason why you got segment fault when define LENGTH = 4*1024.



来源:https://stackoverflow.com/questions/27707319/segmentation-fault-due-to-initialize-function-when-changing-the-size-of-the-hu

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!