mmap函数返回的指针无法访存

nmvbxcz 2016-12-16 09:48:27
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>

#define PAGE_SIZE 4096


int main(int argc, char**argv) {
int fd;
int i;
unsigned char *p_map;

if (argv[1] == NULL) {
printf("command line is empty!\n");
exit(1);
}

fd = open("test.dat", O_RDWR | O_APPEND | O_CREAT);
if (fd<0) {
printf("open failed!\n");
exit(1);
}

p_map = (unsigned char *)mmap(0, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (p_map == MAP_FAILED) {
printf("mmap failed!\n");
goto end;
}

// 读取有效数据
for (i=0;i<PAGE_SIZE;i++) {
if (p_map[i] == 0) {
break;
}
}

printf("length: [%d]\n%s\n", i, p_map);

char * line = argv[1];

printf("line length: %lu\n", strlen(line));

// 复制数据
memcpy(p_map, line, strlen(line));
msync(p_map, strlen(line), MS_SYNC);

close(fd);

end:
munmap(p_map, PAGE_SIZE);
return 0;
}


用gdb调试的时候发现
20 if (argv[1] == NULL) {
(gdb) n
25 fd = open("test.dat", O_RDWR | O_APPEND | O_CREAT);
(gdb) n
26 if (fd<0) {
(gdb) n
31 p_map = (unsigned char *)mmap(0, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
(gdb) n
32 if (p_map == MAP_FAILED) {
(gdb) info local
fd = 3
i = 4196048
p_map = 0x7ffff7ff5000 <error: Cannot access memory at address 0x7ffff7ff5000>
line = 0x0

显示无法访存

然后到了p_map[i]的时候直接报错退出
...全文
345 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
hnzhf777 2016-12-18
  • 打赏
  • 举报
回复
p_map = 0x7ffff7ff5000 <error: Cannot access memory at address 0x7ffff7ff5000>
隐术后生 2016-12-17
  • 打赏
  • 举报
回复
argv[1]==NULL可以替换为argc == 1 argv是参数内容,argc是参数数量,包含运行文件
猪头三小队长 2016-12-17
  • 打赏
  • 举报
回复
猜想是因为文件长度为0,实际上也就是没有任何内存被map上。 你可以尝试创建一个长度为4k的空文件再去实验,等到周一我也可以试试看是怎么回事。
nmvbxcz 2016-12-17
  • 打赏
  • 举报
回复
引用 4 楼 u014486599 的回复:
[quote=引用 2 楼 nmvbxcz 的回复:] [quote=引用 1 楼 u014486599 的回复:] argv[1]==NULL可以替换为argc == 1 argv是参数内容,argc是参数数量,包含运行文件
这不是重点,关键是后面的报错不懂[/quote] 昂昂,看错了,i的数值怎么这么大[/quote] 这也不是重点,因为在for循环里面回重新赋值,你看到的只是未初始化的值
隐术后生 2016-12-17
  • 打赏
  • 举报
回复
引用 2 楼 nmvbxcz 的回复:
[quote=引用 1 楼 u014486599 的回复:] argv[1]==NULL可以替换为argc == 1 argv是参数内容,argc是参数数量,包含运行文件
这不是重点,关键是后面的报错不懂[/quote] 昂昂,看错了,i的数值怎么这么大
  • 打赏
  • 举报
回复
因为你文件里面根本没东西
nmvbxcz 2016-12-17
  • 打赏
  • 举报
回复
引用 1 楼 u014486599 的回复:
argv[1]==NULL可以替换为argc == 1 argv是参数内容,argc是参数数量,包含运行文件
这不是重点,关键是后面的报错不懂

4,441

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 内核源代码研究区
社区管理员
  • 内核源代码研究区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧