gpt4 book ai didi

mmap 的 C 总线错误,问题是什么

转载 作者:行者123 更新时间:2023-11-30 19:01:00 25 4
gpt4 key购买 nike

对于家庭作业,我的教授希望我们使用 mmap 读取文件。然后在对目标文件进行 mmap 后,使用 memcpy 将其复制到另一个文件。我认为我这样做是正确的,但 C 不同意。

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h> // for sleep
#include <time.h> // for the timeing of execution


// for reading and writing the files:
#include <sys/mman.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <assert.h>

#include <string.h>

// create status struct for passing arguments to the threads
typedef struct threadComms{
char* source;
char* destination;

double total_time;
clock_t start;
clock_t end;

// to use the timeing functions,
// when the thread starts, 'start = clock();'
// when the thread ends, 'end = clock();'
// 'total_time = end - start;'
} ThreadComms;


size_t getFileSize(char* filePath){

struct stat st;
stat(filePath, &st);

return st.st_size;
}

void copyFile(void* arg){ // this needs to be a void* for the pthread library


ThreadComms* comms = (ThreadComms*) arg;
// start the counter
comms->start = clock();

size_t fileSize = getFileSize(comms->source);

int sfd = open(comms->source, O_RDONLY, 0);

assert(sfd != -1); // failed to open the file

void* content = mmap(NULL, fileSize, PROT_READ, MAP_PRIVATE | MAP_FILE, sfd, 0); // map the file into the address space

assert(content != MAP_FAILED);
printf("data: %s\n", (char*) content);

int dfd = open(comms->destination, O_CREAT | O_RDWR | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
assert(dfd != -1); // failed to create the file

printf("fileSize: %d\n", (int) fileSize);

printf("1\n");
void* destination = mmap(NULL, fileSize, PROT_READ | PROT_WRITE, MAP_PRIVATE, dfd, 0);
printf("2 destination is: %p\n", destination);

memcpy(destination, content, fileSize);
printf("3\n");

comms->end = clock();
comms->total_time = ((double) (comms->end - comms->start)) / CLOCKS_PER_SEC;
}

int main(int argc, char *argv[]) {

ThreadComms t1;
char* filePath = "/home/csis/tempFile";
char* newFile = "/home/csis/tempFile2";

t1.source = filePath;
t1.destination = newFile;
copyFile(&t1);

// printf("Start: %f, End: %f, Run Time: %f \n", (double)t1.start, (double)t1.end , (double)t1.total_time);
}



我猜测我错误地使用了目的地的文件描述符或者给了它错误的权限。想知道您是否猜测出了什么问题?

最佳答案

您无法通过 mmap() 写入文件不存在的部分。

这会截断文件:

int dfd = open(comms->destination, O_CREAT | O_RDWR | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);

这个mmap()是截断的文件:

void* destination = mmap(NULL, fileSize, PROT_READ | PROT_WRITE, MAP_PRIVATE,  dfd, 0);

这会尝试复制到文件不存在的部分:

memcpy(destination, content, fileSize);

根据 Linux mmap() man page ERRORS :

ERRORS

...

Use of a mapped region can result in these signals:

...

SIGBUS Attempted access to a portion of the buffer that does not correspond to the file (for example, beyond the end of the file, including the case where another process has truncated the file).

the POSIX mmap() specification :

... References within the address range starting at pa and continuing for len bytes to whole pages following the end of an object shall result in delivery of a SIGBUS signal.

An implementation may generate SIGBUS signals when a reference would cause an error in the mapped object, such as out-of-space condition.

解决方法是调用ftruncate()来设置输出文件的文件长度:

ftruncate( dfd, fileSize );
void* destination = mmap(NULL, fileSize, PROT_READ | PROT_WRITE, MAP_SHARED, dfd, 0);

请注意,您还必须将 MAP_PRIVATE 标志替换为 MAP_SHAREDPer POSIX again (加粗我的):

MAP_SHARED and MAP_PRIVATE describe the disposition of write references to the memory object. If MAP_SHARED is specified, write references shall change the underlying object. If MAP_PRIVATE is specified, modifications to the mapped data by the calling process shall be visible only to the calling process and shall not change the underlying object. It is unspecified whether modifications to the underlying object done after the MAP_PRIVATE mapping is established are visible through the MAP_PRIVATE mapping. Either MAP_SHARED or MAP_PRIVATE can be specified, but not both. The mapping type is retained across fork().

关于mmap 的 C 总线错误,问题是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58662861/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com