Segmentation fault in array storing in IPC linux - c++

I am trying to store a array in shared from a process and tring to access the same from another process.
Below is the code I am using to store the array
#include <iostream>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
int count;
int main()
{
while(1)
{
int arr[5] = {1,2,3,4,5};
int *str1;
int key=5678;
// shmget returns an identifier in shmid
int shmid = shmget(key,1024, 0666|IPC_CREAT);
printf("\nShared Memory Id = %d\n",shmid);
// shmat to attach to shared memory
str1 = (int*) shmat(shmid,(void*)0,0);
for(int i=0;i<5;i++)
{
*str1=arr[i];
printf("Data written in memory: %d\n",*str1);
str1++;
}
}
shmdt((void*)str);
return 0;
}
When I am running the program, it is running upto some extend and giving error as segmentation fault (core dumped) and getting exit from the application.
Please help me to solve this problem.
Thanks and regards,
Prabhakar M

str1++ is the culprit.
Below code is working.
#include <iostream>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
int count;
int main()
{
int arr[5] = {1,2,3,4,5};
int *str1;
int key=5678;
// shmget returns an identifier in shmid
int shmid = shmget(key,1024, 0666|IPC_CREAT);
printf("\nShared Memory Id = %d\n",shmid);
// shmat to attach to shared memory
str1 = (int*) shmat(shmid,(void*)0,0);
int *copyAdrr;
copyAdrr = str1 ;
while(1)
{
for(int i=0;i<5;i++)
{
*str1=arr[i];
printf("Data written in memory: %d\n",*str1);
str1++;
}
str1 =copyAdrr;
}
shmdt((void*)str);
return 0;
}

Related

Is there any way to get rid of error "deprecated conversion from string" in this graphic program?

#include <graphics.h>
#include <conio.h>
#include <iostream>
using namespace std;
int main(){
int gd = DETECT,gm;
/* warning deprecated convesion from string to char* [wWrite-strings] */
initgraph(&gd,&gm, "C:\\TURBOC3\\BGI");
circle(300,300,50);
closegraph();
getch();
return 0;
}
Store the string in a modifiable array:
char bgi[] = "C:\\TURBOC3\\BGI";
initgraph(&gd,&gm,bgi);

std::out_of_range for C++ code

I am having errors running this code. While executing it gives out an error like-
terminate called after throwing an instance of 'std::out_of_range'
what(): basic_string::substr
Any ideas on what I am doing wrong here?
#include <string.h>
#include <cstring>
#include <string>
#include <iostream>
#include <fstream>
#include "fix_nvt.h"
#include "group.h"
#include "modify.h"
#include "error.h"
using namespace LAMMPS_NS;
using namespace FixConst;
using namespace std;
std::ifstream inFile;
double x,y,z;
string str_val;
/* ---------------------------------------------------------------------- */
FixNVT::FixNVT(LAMMPS *lmp, int narg, char **arg) :
FixNH(lmp, narg, arg)
{
if (!tstat_flag)
error->all(FLERR,"Temperature control must be used with fix nvt");
if (pstat_flag)
error->all(FLERR,"Pressure control can not be used with fix nvt");
// create a new compute temp style
// id = fix-ID + temp
int n = strlen(id) + 6;
id_temp = new char[n];
strcpy(id_temp,id);
strcat(id_temp,"_temp");
char **newarg = new char*[3];
newarg[0] = id_temp;
newarg[1] = group->names[igroup];
newarg[2] = (char *) "temp";
modify->add_compute(3,newarg);
delete [] newarg;
tflag = 1;
printf("syracuse rocks\n\n\n");
inFile.open("matrix.txt", ios::in);
while(getline(inFile,str_val));
{
x = atof(str_val.substr(1,4).c_str());
y = atof(str_val.substr(17,4).c_str());
z = atof(str_val.substr(33,4).c_str());
printf ("x = %f, y =%f, z=%f\n",x,y,z);
}
inFile.close();
}

Error on call to shmat

Try to do something with shared memory by turning a chunk of user buffer into a shared memory, but the shmat() keep failing.
# ./a.out
shmid=89260087 0x7fbab055c000
shmat failed: : Invalid argument
Here is the source code. Wonder what's the reason. Thanks.
#include <arpa/inet.h>
#include <string.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <malloc.h>
char *output;
int n;
int main (int argc, char *argv[]) {
void *p = NULL;
int i;
double startTS;
double tmp;
output = (char*) valloc(0x1000000);
sprintf(output, "hi you!!");
unsigned int size = 0x1000000;
int shmid = shmget(12348, 0x1000000, IPC_CREAT); //SHM_RDONLY);
printf("shmid=%d %p\n", shmid, &output[0]);
char *bigBuf = (char*)shmat(shmid, &output[0], 0);
if (bigBuf == (void*)-1) {
perror("shmat failed: "); exit(-1);
}
bigBuf[0] = 'x';
printf("%p enter:\n", bigBuf);
scanf("%d\n", &i);
return 0;
}

c++ trying to add Peterson algorithm to avoid race condition in shared memory

I have written two program (program 1 and program 2) to communicate with each other using shared memory. program 1 reads from a file a sentence and pass it after modification to get first letter of each word and its size to the next program ( program 2) . I faced race condition problem. I added Peterson algorithm but once I execute the 2 programs one in foreground and one in background I didn't get any result.
-once i remove the Peterson algorithm my programs work
-i'm working in linux using c++
program 1
#include<iostream>
#include<fstream>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <stdlib.h>
#include <unistd.h>
using namespace std;
int filesize(){
ifstream input;
input.open("file1.txt");
string temp;
int i = 0;
while(input>>temp){i++;}
input.close();
return i;
}
struct shdata
{
char c;
int n;
int size;
bool flag[2];
int turn;
};
int main(){
ifstream input;
input.open("file1.txt");
int shmid;
key_t key = 8006;
struct shdata *shm;
shmid = shmget(key, sizeof(struct shdata), IPC_CREAT | 0666);
if(shmid < 0){
cout<<"Error .. Can not get memory\n";
exit(0);
}
shm = (struct shdata *)shmat (shmid, NULL, 0);
if(shm <= (struct shdata *)(0))
{
cout<<"Errors.. Can not attach\n";
exit(1);
}
shm->flag[0]=false;
shm->flag[1]=true;
string temp;
while(input>>temp){
shm->flag[0]=true;
shm->turn = 1;
while(shm->flag[1]== true && shm-> turn == 1 );
shm->c=temp[0];
shm->n=temp.size();
shm->size = filesize();
shm->flag[0]=false;
sleep(1);
}
return 0;
}
program 2
#include<iostream>
#include<fstream>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <stdlib.h>
#include <unistd.h>
using namespace std;
int filesize(){
ifstream input;
input.open("file1.txt");
string temp;
int i = 0;
while(input>>temp){i++;}
input.close();
return i;
}
struct shdata
{
char c;
int n;
int size;
bool flag[2];
int turn;
};
int main(){
int shmid;
key_t key = 8006;
struct shdata *shm;
shmid = shmget(key, sizeof(struct shdata), 0);
if(shmid < 0)
{
cout<<"Error .. Can not get memory\n";
exit(0);
}
shm = (struct shdata *)shmat (shmid,0, 0);
if(shm <= (struct shdata *)(0))
{
cout<<"Error .. Can not attach\n";
exit(1);
}
int c =0;
while(c<shm->size){
shm->flag[1] = true;
shm->turn=0;
while( shm->flag[0]==false && shm->turn == 0);
sleep(1);
for(int i = 0; i < shm->n ;i++)
{
cout<<shm->c;
}
cout<<endl;
shm->flag[1]=false;
c++;
}
shmctl(shmid, IPC_RMID, NULL);
return 0;
}
program 2 never gets into the while(c<shm->size) loop because at that point shm->size is 0. To get around it, progran 1 should initialize shm->size before program 2 reaches that point. This might lead to another race condition because there doesn't seem to be any mechanism to ensure that the shared memory is initialized by program 1 before program 2 starts using it.
It seems to work without the Peterson algorithm because in that case program 1 doesn't wait on the flag and initializes shm->size further down in the loop.
You are using the flag member to synchronize you 2 programs but this cant work because you cant suppose the sequence of read/writes. You must use a small dialect in order to make your two programs starts in the correct order.

Can I use sem_open in the following program, however I see a crash here?

I am trying to make a tutorial for my students on Shared Memory. However, I see a crash while waiting or posting a semaphore. I am using sem_open API to initialize the semaphore. Do I need to allocate some memory before doing sem_open? It looks to me a segmentation fault. Can you please help me on it?
#include <iostream>
#include <sys/ipc.h>
#include <sys/stat.h>
#include <sys/shm.h>
#include <string.h>
/** page size **/
#include <unistd.h>
/** memcpy **/
#include <stdio.h>
#include <semaphore.h>
#include <fcntl.h>
using namespace std;
class READER_WRITER_A
{
private:
string msg;
void *shm_ptr;
int shm_id;
sem_t *sem_rw;
void Init_Shm();
void Init_Sem();
public:
void Read_Msg();
void Write_Msg(string s1);
READER_WRITER_A();
};
void READER_WRITER_A::Init_Shm()
{
key_t key;
key = ftok("/home/joshis1/Downloads/IPC-BLOG/shm",1);
shm_id = shmget(key, getpagesize(), IPC_CREAT| 0660);
shm_ptr = shmat(shm_id, NULL, 0660);
}
void READER_WRITER_A::Init_Sem()
{
sem_rw = sem_open("/home/joshis1/Downloads/IPC-BLOG/rw_sem", O_RDWR | O_CREAT, 0666, 0);
cout<<"Sem_Post calling"<<endl;
if( sem_rw < 0 )
cout<<"Error in opening the sem_rw"<<endl;
sem_post(sem_rw);
cout<<"Sem_Post done"<<endl;
}
void READER_WRITER_A::Read_Msg()
{
//sem_wait(sem_rw);
int *size = (int *)shm_ptr;
void *msg_ptr = shm_ptr;
msg_ptr+=sizeof(int);
cout<<"Message size is = "<<*size<<endl;
memcpy(&msg,(string *)msg_ptr,*size);
cout<<"Reading Message-- "<<msg<<endl;
//sem_post(sem_rw);
}
void READER_WRITER_A::Write_Msg(string s1)
{
//sem_wait(sem_rw);
void *msg_ptr = shm_ptr;
msg = s1;
int *pt = (int*)shm_ptr;
*pt = s1.size();
cout<<"Writing Message size = "<<*pt<<endl;
msg_ptr+=sizeof(int);
cout<<"Writing Message-- "<<s1<<endl;
memcpy((string *)msg_ptr,&msg,s1.size());
//sem_post(sem_rw);
}
READER_WRITER_A::READER_WRITER_A()
{
Init_Shm();
Init_Sem();
}
int main( int argc, char *argv[])
{
READER_WRITER_A val;
val.Write_Msg("I am A-RW");
val.Read_Msg();
return 0;
}
Here is the output.
$ ./reader_writer_a.out
Sem_Post calling
Segmentation fault (core dumped)
Analyzing coredump here.
(gdb) bt
#0 0x0000003fb060d790 in sem_post () from /lib64/libpthread.so.0
#1 0x0000000000400fd0 in READER_WRITER_A::Init_Sem (this=0x7fff50e322a0) at reader_writer_a.cpp:52
#2 0x0000000000401199 in READER_WRITER_A::READER_WRITER_A (this=0x7fff50e322a0) at reader_writer_a.cpp:86
#3 0x00000000004011d8 in main (argc=1, argv=0x7fff50e323c8) at reader_writer_a.cpp:92
void READER_WRITER_A::Init_Sem()
{
sem_rw = sem_open("/home/joshis1/Downloads/IPC-BLOG/rw_sem", O_RDWR | O_CREAT, 0666, 0);
cout<<"Sem_Post calling"<<endl;
if( sem_rw < 0 )
cout<<"Error in opening the sem_rw"<<endl;
sem_post(sem_rw);
cout<<"Sem_Post done"<<endl;
}
sem_open() returns SEM_FAILED on failure and otherwise it's an address. It doesn't make sense to check it against 0.
If it failed, your sem_post() call might crash the program