问题
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