c++ - 不太清楚为什么 mmap 没有按照我认为应该的方式进行。 C++ Linux

标签 c++ linux mmap coredump

我试图制作一个日志文件类,我想遵循的过程是:

  • 打开文件(或创建文件)
  • 将文件映射到内存
  • 关闭文件
  • 写入内存

文件的大小为 1024KB(SIZE_KB 常量)。

到目前为止,这就是我正在做的:

我创建的文件具有所有者的读写权限 (S_IRUSR | S_IWUSR) 和其余的读取权限 (S_IRGRP | S_IROTH)。

// Open the file. If the file doesnt exists it will create it
mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
int fd = open(path.c_str(), O_CREAT | O_RDWR, mode);

之后,我检查 fd 是否为 -1:

if (fd < 0)
    throw std::system_error(errno, std::system_category(), "couldnt open history");

#ifdef _DEBUG_
    std::clog << "History with file descriptor " << fd << " opened" << std::endl;
#endif

现在,我映射文件,但首先我需要设置一个可变长度,该文件的大小必须是 sysconf(_SC_PAGE_SIZE) 的倍数:

size_t length = (int)ceil(SIZE_KB*1024.0/sysconf(_SC_PAGE_SIZE))*sysconf(_SC_PAGE_SIZE);  
/* ceil( size / page_size)*page_size*/

#ifdef _DEBUG_
    std::clog << "Length is " << length << " bytes" << std::endl;
#endif

映射,block_start是一个私有(private)的char指针:

block_start = (char*)mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
  • 附加问题:M_SHARED 选项使这部分内存可以被其他进程访问(?)。为什么还用它来让SO把虚拟内存中的修改保存到实际文件中?。

检查错误:

#ifdef _DEBUG_  
    std::clog << Returned: " << (int*)block_start << std::endl;
#endif

if (block_start == MAP_FAILED)
    throw std::system_error(errno, std::system_category(), "couldnt map memory");

#ifdef _DEBUG_
    std::clog << "History memory mapped" << std::endl;
#endif

然后关闭文件:

int result = close(fd);
if (result < 0)
    throw std::system_error(errno, std::system_category(), "error closing history");

#ifdef _DEBUG_
    std::clog << "History with file descriptor " << fd << " closed" << std::endl;
#endif

现在,我应该能够将信息添加到映射内存中,所以我尝试这样做:

std::cout << "Attemping to write on first" << std::endl;
*block_start = 'A';
std::cout << "End" << std::endl;

(在构造函数内部)

这是我的输出:

History with file descriptor 3 opened
Length is 1048576 bytes
Returned: 0x7f7e9160a000
History memory mapped
History with file descriptor 3 closed
Attemping to write on first
Bus error (core dumped)

我认为这可能与文件大小有关,因为创建的文件大小为 0,但我告诉 mmap 映射大小为 SIZE_KB*1024 字节,那么为什么这不起作用?

-rw-r--r-- 1 dark dark 0 Dec 13 16:15 /home/dark/talk.log

最佳答案

因为 mmap 不会映射超出文件大小。如果您正在映射一个空文件,则您的有效 mmap 大小为 0。

在映射之前,您需要通过 truncate() 或 ftruncate() 设置文件的大小,并且文件的大小和映射的大小必须一致。

关于c++ - 不太清楚为什么 mmap 没有按照我认为应该的方式进行。 C++ Linux,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34254043/

相关文章:

c++ - 在这种情况下, “typename…”是什么意思?

c - 有没有办法让程序在等待输入时保持运行?

linux - 减少 bash 脚本中命令的重复

c++ - g++/make 链接目标文件时失败

c++ - 整数作为 8 传递给函数,但函数内部的值是 -439854520

linux - 如何安装 libprotobuf?

c - 无法使用 mmap 从结构中读取指针

c - 如何 mmap() 更正地址

c++ - 共享内存或 mmap - Linux C/C++ IPC

c++ - 如何在运行控制台时更改文本