shm_open 分段错误和权限失败
shm_open segmentation fault and permission failed
我是 Linux 的新手,我正在尝试创建一个共享内存对象,它存储在子进程中计算的 collatz 猜想并在父进程中打印它。我已经阅读了命令的手册页。
当我创建对象时,它会打印权限被拒绝和分段错误(核心已转储)。只有一次它以某种方式通过了那一步然后我得到映射失败 error.I 我在虚拟机上使用 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;
}
我是 Linux 的新手,我正在尝试创建一个共享内存对象,它存储在子进程中计算的 collatz 猜想并在父进程中打印它。我已经阅读了命令的手册页。 当我创建对象时,它会打印权限被拒绝和分段错误(核心已转储)。只有一次它以某种方式通过了那一步然后我得到映射失败 error.I 我在虚拟机上使用 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;
}