由于分段错误改变了巨大的页面分配的大小时进行初始化()函数 [英] segmentation fault due to initialize() function when changing the size of the huge page allocation
问题描述
我遇到段错误在我的计划时,我与我要和巨大的页面,也就是分配内存的大小,玩的时候我定义长度= 4 * 1024,有赛格故障。当我定义4 * 1024 * 1024,没有赛格故障。这什么的根本原因?
code如下:
的#define _POSIX_C_SOURCE 199309
#定义_GNU_SOURCE
#包括LT&;&sched.h中GT;
#包括LT&;&stdio.h中GT;
#包括LT&;&stdlib.h中GT;
#包括LT&;&unistd.h中GT;
#包括LT&; SYS / mman.h>
#包括LT&;&fcntl.h GT;
#包括LT&;&time.h中GT;
#包括LT&;&string.h中GT;
#包括LT&;&errno.h中GT;#定义保护(PROT_READ | PROT_WRITE)
的#define长度(4 * 1024)
//#定义长度(4 * 1024 * 1024)
#定义LINE_SIZE 64
#定义ASSOC 16
的#define CACHE_SIZE(4 * 1024 * 1024)
#定义WAY_SIZE(CACHE_SIZE / ASSOC)的#ifndef MAP_HUGETLB
#定义MAP_HUGETLB 0x40000
#万一#定义ADDR(无效*)(0x0UL)
#定义标志(MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB)INT主(INT ARGC,CHAR *的argv []){
...
//如使用巨大的页面LLC分配一个缓冲器具有相同大小
BUF = MMAP(ADDR,长度,保护,旗帜,0,0);
如果(BUF == MAP_FAILED){
PERROR(MMAP);
出口(1);
}
set_S =的atoi(ARGV [1]);
set_M =与atoi(argv的[2]);
的printf(测试0 \\ n);
初始化(set_S);
的printf(测试1 \\ n);
初始化(set_M);
的printf(测试2 \\ n);
head_S =安培; BUF [set_S * LINE_SIZE]。
的printf(测试3 \\ n);
head_M =安培; BUF [set_M * LINE_SIZE]。...
}
需要注意的是在我的电脑默认启用没有庞大的页面,所以我把它作为根:
回声20 GT;的/ proc / SYS / VM / nr_hugepages
这是在/ proc / meminfo中我打开巨大的页面后,页面庞大的相关信息:
HugePages_Total:20
HugePages_Free:20
HugePages_Rsvd:0
HugePages_Surp:0
Hugepagesize:2048 KB
程序输出:
$。/ a.out的1 1
测试0
分段错误(核心转储)
$的uname输出:
Linux的mymachine上3.13.0-43泛型#72 Ubuntu的SMP周一12月8日19时35分06秒UTC 2014年的x86_64 x86_64的x86_64的GNU / Linux的
编辑1:添加初始化函数:
void初始化(INT组){
INT J,K;
焦炭** ptr1的,** PTR2;
字符* tmp目录; //重新初始化大小大小的指针数组
//执行Sattolo的随机循环置换
为(J = 0; J< ASSOC; J ++){
ptr1的=(字符**)及BUF [设置* LINE_SIZE + J * WAY_SIZE]。
* ptr1的=(字符*)ptr1的;
} //置换每组
为(J = ASSOC-1,J> = 1;的J - ){
K =兰特()%焦耳;
ptr1的=(字符**)及BUF [设置* LINE_SIZE + J * WAY_SIZE]。
PTR2 =(字符**)及BUF [设置* LINE_SIZE + K * WAY_SIZE]。
TMP = * ptr1的;
* ptr1的= * PTR2;
* PTR2 = tmp目录;
}
}
当访问设置* LINE_SIZE +(ASSOC-1)* WAY_SIZE =设置* 64 + CACHE_SIZE - WAY_SIZE =设置* 64 + 4 * 1024 * 1024 - WAY_SIZE
比MMAP长度长度= 4 * 1024
在的环路初始化$大C $ C>,您正在访问的内存越界。这就是为什么你有段故障时定义长度的原因= 4 * 1024。
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;
}
}
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.
这篇关于由于分段错误改变了巨大的页面分配的大小时进行初始化()函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!