Arm-Linux(二)共享記憶體
阿新 • • 發佈:2021-01-05
在學習Linux程序間通訊時,仿照書上的思路寫了一個用共享記憶體銅棍的例子,其中父程序向分配的共享記憶體內傳送資訊,子程序接收資訊,原始碼如下:
/* *************************************************
* 檔名:
* 建立人:px
* 建立時間:2021/1/4
* 描述:共享記憶體demo
************************************************* */
#include<stdio.h>
#include<stdlib.h>
#include <sys/ipc.h>
#include<sys/shm.h>
#include<string.h>
#include<unistd.h>
int main()
{
int pid,shmid;
char* read_add;
char* write_add;
printf("the address of write_add:%x\n",&write_add);
struct shmid_ds dsbuf;
// Allocate shared memory
if(( shmid=shmget(IPC_PRIVATE,32,0))<0)
{
printf("Allocate shared memory error\n");
exit(1);
}
else
{
printf("Allocate shared memory success\n");
}
//create child process
pid=fork();
if(pid<0)
{
printf("Creat child process failed\n" );
exit(2);
}
else if(pid>0) //Parent process
{
printf("Parent process is %d\n",getpid());
//link shared memory
write_add=(char*)shmat(shmid,NULL,0);
printf("Shared memory has established,the address of write_add is %x\n",&write_add);
if(sizeof(write_add) <= 1)
{
printf("Link shared memory failed\n");
exit(3);
}
else
{
printf("Link shared memory success\n");
strcpy(write_add,"Test information\n");
printf("write information:%s",write_add);
//disable connect
if((shmdt((void*)write_add))<0)
{
printf("Disable connect failed\n");
}
else
{
printf("Disable connect success\n");
}
sleep(2);
return 0;
}
}
else if (pid==0)
{
sleep(2);
printf("The ID of child process is %d\n",getpid());
if((shmctl(shmid,IPC_STAT,&dsbuf))<0)
{
printf("Get the state of shared memory failed\n");
exit(4);
}
else
{
printf("Get the state of shared memory success\n");
printf("The size of shared memory is %d\n",dsbuf.shm_segsz);
if((read_add=(char*)shmat(shmid,0,0))<0)
{
printf("shmat link error\n");
exit(5);
}
else
{
printf("The information geted is :%s",read_add);
printf("The latest operated process is:%d\n",dsbuf.shm_lpid);
if((shmdt((void*)read_add))<0)
{
printf("shmdt delete shared memory error\n");
exit(6);
}
else
{
printf("shmdt delete shared memory success\n");
exit(0);
}
}
}
}
}
在執行時卻總是報Segmentation fault 的錯誤,這個錯誤意味著程序訪問了不該訪問的記憶體。
經過GDB Debug,發現是父程序在向共享記憶體區域內拷貝資訊時產生的錯誤。
strcpy(write_add,"Test information\n");
也是在Debug的過程中發現,write_add這個變數在宣告的地址和read_buf是鄰近的,當執行完下面這個分配共享記憶體的指令後,地址就變成了0xfffffffffff:
根據查到的遇到類似問題的解決方法,懷疑是沒有預先給write_add分配記憶體,所以嘗試先用malloc分配記憶體再執行,但還是同樣的錯誤。
所以這裡猜測是父程序在執行strcpy時沒有許可權向這塊記憶體中寫入資料,因此在執行時用sudo來執行,發現可以解決問題,但是否是因為許可權的問題才發生段錯誤的,還需要進一步查明。