c - shm_open 分段错误和权限失败
问题描述
我是 Linux 新手,我正在尝试创建一个共享内存对象,该对象存储在子进程中计算的 collatz 猜想并将其打印在父进程中。我已经阅读了命令的手册页。当我创建对象时,它会打印权限被拒绝和分段错误(核心转储)。只有一次它以某种方式通过了该步骤,然后我得到了映射失败错误。我在虚拟机上使用 ubuntu 18.04
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<fcntl.h>
#include<sys/mman.h>
#include<sys/wait.h>
#include<sys/stat.h>
int main(int argc,char** argv)
{
pid_t pid;
pid = fork();
int page_size = 4096;
char obj[] = "name";
int num = atoi(argv[1]);
if(num < 1)
{
printf("Please input a greater number\n");
return 0;
}
if(pid < 0)
{
fprintf(stdout,"Fork failed\n");
}
else if(pid == 0)
{
int fd1 = 0;
void *ptr1 = NULL;
fd1 = shm_open(obj,O_CREAT|O_TRUNC,S_IRWXU);
if (fd1 == -1)
{
perror("error:");
exit(0);
}
ftruncate(fd1,page_size);
ptr1 = mmap(0,page_size,PROT_WRITE,MAP_SHARED,fd1,0);
if(ptr1 == MAP_FAILED)
{
fprintf(stdout,"Mapping failed");
exit(0);
}
else
{
while(num != 1)
{
if(num%2 == 0)
num = num / 2;
else
num = (num * 3) + 1;
sprintf(ptr1,"%d, ",num);
}
}
}
else
{
wait(NULL);
int fd = 0;
void *ptr = NULL;
shm_open(obj,O_RDONLY,S_IRWXU);
ptr = mmap(0,page_size,PROT_READ,MAP_SHARED,fd,0);
char *pr = (char *)ptr;
fprintf(stdout,pr);
shm_unlink(obj);
}
return 0;
}
解决方案
您的代码需要进行一些更改,一些用于更好的编程实践,一些用于修复实际功能:
#include <all.h>
int main(int argc, char **argv) {
pid_t pid;
pid = fork();
int page_size = 4096;
char obj[] = "name";
// check argc otherwise you'll segfault
if (argc < 2) {
printf("Please provide a second argument.\n");
// if the program errors it should not return 0
return 1;
}
int num = atoi(argv[1]);
if (num < 1) {
printf("Please input a greater number\n");
return 1;
}
if (pid < 0) {
// no need for fprintf(stdout
printf("Fork failed\n");
} else if (pid == 0) {
int fd1 = 0;
char *ptr1 = NULL;
// we need to open with O_RDWR otherwise mmap will fail
fd1 = shm_open(obj, O_CREAT | O_TRUNC | O_RDWR, 0666);
if (fd1 == -1) {
perror("shm_open error");
return 1;
}
ftruncate(fd1, page_size);
// cast it to char* directly, no need for void pointer stuff
ptr1 = (char *) mmap(0, page_size, PROT_WRITE, MAP_SHARED, fd1, 0);
if (ptr1 == MAP_FAILED) {
// perror for debugging
perror("mmap error");
printf("Mapping failed.\n");
return 1;
} else {
while (num != 1) {
if (num % 2 == 0)
num = num / 2;
else
num = (num * 3) + 1;
// we need to shift the pointer so it stops truncating
ptr1 += sprintf(ptr1, "%d, ", num);
}
}
} else {
wait(NULL);
// move these to one like and cast to char* directly
int fd = shm_open(obj, O_RDONLY, S_IRWXU);
char *ptr = (char*) mmap(0, page_size, PROT_READ, MAP_SHARED, fd, 0);
// no need for fprintf(stdout, and also use %s\n as a format to add a newline
printf("%s\n", ptr);
shm_unlink(obj);
}
return 0;
}
推荐阅读
- javascript - 无法解构“this.props.data”的属性“聊天”,因为它未定义
- puppeteer - 在 puppeteer headful 模式下处理打印对话框
- python - 如何使用python验证给定的URL是域还是子域或确切的页面?
- regex - 正则表达式提取文本和第一个 > 字符之间的所有内容
- javascript - 使用 for...in 循环时,数组索引不响应严格相等
- python - Python异步写入数据库
- java - Spring Boot App:.war 包和 Docker 构建后无法访问 html 文件
- docker - 在 ubuntu 中回显 $USER 打印空白
- php - 如何使用 PHP 从 Mysql 中获取的数据中创建不定数量的 CSS div
- flutter - 当底部导航栏存在时,appbar 与通知栏重叠