LinuxQuestions.org
Review your favorite Linux distribution.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 01-08-2011, 11:26 AM   #1
hashmal
LQ Newbie
 
Registered: Jan 2011
Posts: 3

Rep: Reputation: 0
segmentation fault using shared memory


Hi!
I'm writing a producer-consumer program, where the producer and the consumer are different processes and they communicate using queued signals, and when I run it it comes out always 'segmentation fault'.
Please, can anyone help me? thank you a lot!!
Here is my code:
(note: I tried using both 'shm_open()' and 'mmap()', and 'shmget()' and shmat()')

Code:
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <pthread.h>

#define T 11
#define N 10
#define M 10
#define STATE_FILE "/shared_memory"

int full=0,empty=1;
pthread_mutex_t *mutex;

typedef struct shop
{
	int n;
	char *obj;
}shop;

void handler_producer(int sig,siginfo_t *info,void *other){
	full = info->si_value.sival_int;	
}

void handler_consumer(int sig,siginfo_t *info,void *other){
	empty = info->si_value.sival_int;	
}

void producer(shop *s,pid_t cons){
	int i=0,j;
	char stuff[M];
	union sigval flag;
	sigset_t set;
	struct sigaction act;
	siginfo_t info;
	sigemptyset (&set);
	sigaddset (&set, SIGRTMIN+1);
	act.sa_flags = SA_SIGINFO;
	act.sa_mask = set;
	act.sa_sigaction = &handler_producer;
	sigaction (SIGRTMIN+1, &act, NULL);

	s->n=0;	

	do {
		while (full){}

		pthread_mutex_lock(mutex);
		j=rand()%26;
		stuff[i%M]='A'+j;
		printf("The producer produced a: %c\n",stuff[i%M]);
		
		j=rand()%M;
		s->obj[i]=stuff[j];
		s->n++;
		i=(i+1)%N;
		flag.sival_int = 0;
		sigqueue (cons, SIGRTMIN, flag);
		pthread_mutex_unlock(mutex);

	} while (i<T);

}

void consumer(shop *s){
	int k=0,h;
	char bag,house[M];
	union sigval flag;
	sigset_t set;
	struct sigaction act;
	siginfo_t info;
	sigemptyset (&set);
	sigaddset (&set, SIGRTMIN);
	act.sa_flags = SA_SIGINFO;
	act.sa_mask = set;
	act.sa_sigaction = &handler_consumer;
	sigaction (SIGRTMIN, &act, NULL);

	do {
		while (empty){}

		pthread_mutex_lock(mutex);	
		bag=s->obj[k];
		s->obj[k]=' ';
		s->n--;
		k=(k+1)%N;
		flag.sival_int = 0;
		sigqueue (getppid(), SIGRTMIN+1, flag);
		pthread_mutex_unlock(mutex);
		h=rand()%M;
		house[h]=bag;
		printf("The consumer got a: %c\n",house[h]);

	} while (k<T);

	// sleep (2);
}

main(){
	pid_t pid;
	shop *market,market1;
	char buffer[N];
	int shm,shm_mutex;
	
	srand(1);
	market=&market1;
	market->obj=buffer;	

	/*mutex = (pthread_mutex_t *)mmap (NULL, sizeof(pthread_mutex_t),(PROT_READ | PROT_WRITE),(MAP_SHARED | MAP_ANON),-1, 0);

	if ((shm = shm_open(STATE_FILE,(O_CREAT | O_EXCL | O_RDWR),(S_IRUSR | S_IWUSR))) < 0){
		printf("Error creating shared memory: %s\n",strerror(errno));
		return errno;
	}

	ftruncate(shm,sizeof(shop));

	if ((market = (shop *)mmap(NULL,sizeof(shop),(PROT_READ | PROT_WRITE),MAP_SHARED,shm,0)) == MAP_FAILED){
		printf("Error mapping shared memory: %s\n",strerror(errno));
		return errno;
	}*/

	shm_mutex = shmget(IPC_PRIVATE,sizeof(pthread_mutex_t),(IPC_CREAT | IPC_EXCL));
	mutex = (pthread_mutex_t *)shmat(shm_mutex,0,0);
	
	if ((shm = shmget(IPC_PRIVATE,sizeof(shop),(IPC_CREAT | IPC_EXCL))) < 0){
		printf("Error creating shared memory: %s\n",strerror(errno));
		return errno;
	}

	if ((market = (shop *)shmat(shm,0,0)) < 0) {
		printf("Error mapping shared memory: %s\n",strerror(errno));
		return errno;
	}

	pid = fork();

	if (pid == 0)
		consumer(market);
	else
		producer(market,pid);

}

Last edited by hashmal; 01-08-2011 at 09:26 PM.
 
Old 01-08-2011, 02:06 PM   #2
theNbomr
LQ 5k Club
 
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,399
Blog Entries: 2

Rep: Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908
Your first problem has nothing to do with shared memory. You dereference the uninitialized pointer 'market'. You should have been able to get at least past that simple problem with a debugger or a handful of printf()s to see where things go south.
Please post your source code in [ code] tags.

--- rod.
 
Old 01-08-2011, 09:39 PM   #3
hashmal
LQ Newbie
 
Registered: Jan 2011
Posts: 3

Original Poster
Rep: Reputation: 0
Quote:
Originally Posted by theNbomr View Post
Your first problem has nothing to do with shared memory. You dereference the uninitialized pointer 'market'. You should have been able to get at least past that simple problem with a debugger or a handful of printf()s to see where things go south.
Please post your source code in [ code] tags.

--- rod.
Thank you for making me notice the error, but I was so concentrated looking at shared memory sintax that I didn't pay attention to it, also I found out another problem about the syncronization between the two processes and I fixed it by 'shared mutex'. I corrected the code for both the problems but it still says 'segmentation fault'. I posted in this forum without making any kind of debug just because I thought there was an error easy to find... anyway i'll try to do some debug, but if someone is able to find out the problem i'll be very thankful!
 
Old 01-09-2011, 08:32 AM   #4
johnsfine
LQ Guru
 
Registered: Dec 2007
Distribution: Centos
Posts: 5,286

Rep: Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197
Quote:
Originally Posted by hashmal View Post
I corrected the code for both the problems but it still says 'segmentation fault'.
It appears you edited your first post to put those corrections directly into the code shown there. Others trying to help you probably wouldn't notice you did that, so they would assume they can't help because they don't know the current state of your code.

It is generally better to leave the wrong code in the initial post and post the corrected code in a later post.

Quote:
I posted in this forum without making any kind of debug just because I thought there was an error easy to find.
That is a large enough amount of code, that I would want to know where the seg fault occurs before attempting to desk check the code for the cause of the seg fault.

Quote:
anyway i'll try to do some debug, but if someone is able to find out the problem i'll be very thankful!
The most trivial debugging can find the location and backtrace of the seg fault. It may take more skill to find the reason for the seg fault.

If you wanted help, you should have done the first debugging step and posted the backtrace of the seg fault.
 
Old 01-09-2011, 03:21 PM   #5
theNbomr
LQ 5k Club
 
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,399
Blog Entries: 2

Rep: Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908
You should very carefully re-read the shmat() manpage, especially anything to do with its return value. That shouldn't be too hard for you; it wasn't for me.

--- rod.
 
0 members found this post helpful.
Old 01-09-2011, 03:54 PM   #6
johnsfine
LQ Guru
 
Registered: Dec 2007
Distribution: Centos
Posts: 5,286

Rep: Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197
Edit: I buried a key fact for the OP too deep in this rambling post, so copying it to the top:

Comparison of x86 pointers is unsigned. There is no pointer p that could make the comparison p<0 true.

(void*)-1 is the maximum possible pointer and thus > all other pointer values.

Quote:
Originally Posted by theNbomr View Post
You should very carefully re-read the shmat() manpage, especially anything to do with its return value. That shouldn't be too hard for you; it wasn't for me.
I assume you're trying to make the OP feel stupid. I haven't tried as hard as the OP should have, but I don't see how the answer is in the shmat() manpage.

I pasted the code into a file, added an include of string.h (because it wouldn't compile for me without that) and ran it.

It crashes on the line
Code:
              s->n=0;
because s is 0xFFFFFFFF, which is because market is 0xFFFFFFFF from executing the line:

Code:
    if ((market = (shop *)shmat(shm,0,0)) < 0)
I assume the OP already understood that 0xFFFFFFFF is the documented error return from shmat(), but probably doesn't understand why the <0 test didn't work for 0xFFFFFFFF, nor why shmat() returned error.

I would never have coded a <0 test on a pointer myself. I have no idea what such a test should mean. Comparison of two pointers is unsigned so 0xFFFFFFFF is the max pointer and not < any other pointer. But 0, if it is a pointer is <= all pointers, so the test is already false at compile time.

I might have coded
Code:
    if ((market = (shop *)shmat(shm,0,0)) == (shop*)(-1))
That causes the program to display:
Code:
Error mapping shared memory: Permission denied

Last edited by johnsfine; 01-09-2011 at 04:25 PM.
 
1 members found this post helpful.
Old 01-09-2011, 04:38 PM   #7
johnsfine
LQ Guru
 
Registered: Dec 2007
Distribution: Centos
Posts: 5,286

Rep: Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197
Quote:
Originally Posted by johnsfine View Post
If you wanted help, you should have done the first debugging step and posted the backtrace of the seg fault.
As it happened, theNbomr made me curious enough that I copied/pasted/compiled your code and started it in gdb. So I saw that the fault was on
Code:
    s->n=0;
From there, I have the experience to jump directly to the <0 bug discussed above (that I didn't have the patience to read your entire source to spot).

You should know how easy it is to identify the faulting line (with -g on your g++ command and then gdb).

You could have had that answer in my first post (or maybe even earlier from someone else) rather than waiting hours for it, if you had done that simple step yourself.
 
Old 01-09-2011, 05:35 PM   #8
theNbomr
LQ 5k Club
 
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,399
Blog Entries: 2

Rep: Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908
Quote:
Originally Posted by johnsfine View Post
I assume you're trying to make the OP feel stupid. I haven't tried as hard as the OP should have, but I don't see how the answer is in the shmat() manpage.
Not stupid, but a bit short on ambition. He/she has shown little that there was any effort to solve the problem. As you have correctly pointed out, the problem results from an incorrect test of a return value. The details of this are explained in the manpage (at least in the one I read), and I think I pointed to a pretty specific part of that page.

EDIT: There seems to other problems with the code, as the pointer 'market' is first initialized, and then used to assign to a member of the struct to which it points. Then it is changed to be a pointer to shared memory, or at least attempted, without ever having made use of the original struct. It might be useful to give us some idea how the program is intended to work.

--- rod.

Last edited by theNbomr; 01-09-2011 at 05:41 PM.
 
Old 01-09-2011, 05:55 PM   #9
johnsfine
LQ Guru
 
Registered: Dec 2007
Distribution: Centos
Posts: 5,286

Rep: Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197
Quote:
Originally Posted by theNbomr View Post
The details of this are explained in the manpage (at least in the one I read)
I think we're looking at similar enough manpages that we disagree despite seeing the same thing.

The manpage says the error return is -1. There is every reason to assume the OP understood that. The manpage does not tell you how a C++ program can compare a pointer to -1 (nor should it). A C++ programmer ought to know that, but most don't. A naive programmer might try (pointer==-1) and discover that is wrong (at compile time), then decide to get lazy and think (pointer<0) is good enough (because the compiler didn't complain).

Quote:
EDIT: There seems to other problems with the code
For sure, especially the important one I don't know the answer to (don't ever use shmat myself), which is what makes that shmat() fail. That is also discussed in the manpage, which lists several possibilities, none of which seem to apply to my test.

Quote:
as the pointer 'market' is first initialized, and then used to assign to a member of the struct to which it points. Then it is changed to be a pointer to shared memory, or at least attempted, without ever having made use of the original struct.
I didn't even look at that until you mentioned it. You're right of course, but I expect the OP is first focussed on getting the shared memory use to work and would look at program logic issues after that. I expect you are not implying that specific program logic error is part of the cause of the failure of the use of shared memory.

Last edited by johnsfine; 01-09-2011 at 05:56 PM.
 
Old 01-09-2011, 06:35 PM   #10
theNbomr
LQ 5k Club
 
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,399
Blog Entries: 2

Rep: Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908
Ok, my man page explicitly states that 'on error (void *) -1 is returned'. This seems like enough of a hint that a simple test against less-than-zero is not enough.

At this stage, I don't consider the program to be failing; at least not the version I have tested (and I also found all of the problems you previously noted, along with a couple of benign things, thanks to the -Wall compiler switch). It properly tests and handles the return value. When I ran it at as root, it reported something resembling success, and left a child process running. Not too sure I will do that again, at least until I've satisfied myself that any bugs are at worst harmless.

--- rod.

Last edited by theNbomr; 01-09-2011 at 06:36 PM.
 
Old 01-09-2011, 07:33 PM   #11
hashmal
LQ Newbie
 
Registered: Jan 2011
Posts: 3

Original Poster
Rep: Reputation: 0
Quote:
Originally Posted by johnsfine View Post
It appears you edited your first post to put those corrections directly into the code shown there. Others trying to help you probably wouldn't notice you did that, so they would assume they can't help because they don't know the current state of your code.
It is generally better to leave the wrong code in the initial post and post the corrected code in a later post.
Thank you for the hints! As you said I'm new in this kind of forum so I have to learn lots of things.


Quote:
That is a large enough amount of code, that I would want to know where the seg fault occurs before attempting to desk check the code for the cause of the seg fault.
The most trivial debugging can find the location and backtrace of the seg fault. It may take more skill to find the reason for the seg fault.
If you wanted help, you should have done the first debugging step and posted the backtrace of the seg fault.
I found the problem which caused seg fault: using shmat() the address of mutex was 0xffffff (as you wrote in the last postes), while using mmap() the address of market->obj was 0x0. So I solved the problem using the last one and referencing market->obj=buffer after mapping.
Now the problem is that the program doesn't work well, it works only the producer and also using the debugger I saw it never enters in the consumer function, like the program doesn't fork and I don't understand why..
I hope this time someone will able to help me. Here's the corrected code:

Code:
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <pthread.h>

#define T 9
#define N 10
#define M 10
#define STATE_FILE "/shared_memory"

int full=0,empty=1;
pthread_mutex_t *mutex,mutex1;

typedef struct shop
{
	int n;
	char *obj;
}shop;

void handler_producer(int sig,siginfo_t *info,void *other){
	full = info->si_value.sival_int;	
}

void handler_consumer(int sig,siginfo_t *info,void *other){
	empty = info->si_value.sival_int;	
}

void producer(shop *s,pid_t cons){
	int i=0,j;
	char stuff[M];
	union sigval flag;
	sigset_t set;
	struct sigaction act;
	siginfo_t info;
	sigemptyset (&set);
	sigaddset (&set, SIGRTMIN+1);
	act.sa_flags = SA_SIGINFO;
	act.sa_mask = set;
	act.sa_sigaction = &handler_producer;
	sigaction (SIGRTMIN+1, &act, NULL);

	do {
		while (full){}

		pthread_mutex_lock(mutex);
		j=rand()%26;
		stuff[i%M]='A'+j;
		printf("The producer produced a: %c\n",stuff[i%M]);

		s->obj[i]=stuff[i%M];
		s->n++;
		i=(i+1)%N;
		flag.sival_int = 0;
		sigqueue (cons, SIGRTMIN, flag);
		pthread_mutex_unlock(mutex);
		//sleep (1);

	} while (i<T);

}

void consumer(shop *s){
	int k=0,h;
	char bag,house[M];
	union sigval flag;
	sigset_t set;
	struct sigaction act;
	siginfo_t info;
	sigemptyset (&set);
	sigaddset (&set, SIGRTMIN);
	act.sa_flags = SA_SIGINFO;
	act.sa_mask = set;
	act.sa_sigaction = &handler_consumer;
	sigaction (SIGRTMIN, &act, NULL);

	do {
		while (empty){}

		pthread_mutex_lock(mutex);
		h=rand()%(s->n);	
		bag=s->obj[h];
		s->obj[h]=' ';
		s->n--;
		k=(k+1)%N;
		flag.sival_int = 0;
		sigqueue (getppid(), SIGRTMIN+1, flag);
		
		h=rand()%M;
		house[h]=bag;
		printf("The consumer got a: %c\n",house[h]);
		pthread_mutex_unlock(mutex);

	} while (k<T);

	//sleep (2);
}

main(){
	pid_t pid;
	shop *market,market1;
	char buffer[N];
	int shm,shm_mutex;
	
	srand(1);
	market=&market1;
	mutex=&mutex1;	

	/*if ((shm = shm_open(STATE_FILE,(O_CREAT | O_EXCL | O_RDWR),(S_IRUSR | S_IWUSR))) < 0){
		printf("Error creating shared memory: %s\n",strerror(errno));
		return errno;
	}

	ftruncate(shm,sizeof(shop));*/

	if ((mutex = (pthread_mutex_t *)mmap (NULL, sizeof(pthread_mutex_t),(PROT_READ | PROT_WRITE),(MAP_SHARED | MAP_ANON),-1, 0)) == MAP_FAILED){
		printf("Error mapping shared memory 'mutex': %s\n",strerror(errno));
		return errno;
	}

	if ((market = (shop *)mmap(NULL,sizeof(shop),(PROT_READ | PROT_WRITE),(MAP_SHARED | MAP_ANON),-1,0)) == MAP_FAILED){
		printf("Error mapping shared memory 'market': %s\n",strerror(errno));
		return errno;
	}

	market->n=0;
	market->obj=buffer;
	pid = fork();

	if (pid == 0)
		consumer(market);
	else
		producer(market,pid);

	//close(shm);

}

Last edited by hashmal; 01-09-2011 at 07:37 PM.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Segmentation Fault in Shared Memory the_satsuma_man Programming 3 03-03-2009 03:39 PM
Segmentation Fault - memory problem? felipebil Programming 10 11-19-2008 10:01 PM
Difference between resident memory,shared memory and virtual memory in system monitor mathimca05 Linux - Newbie 1 11-11-2007 04:05 AM
Segmentation Fault, Should I try new memory M$ISBS Linux - Hardware 10 07-04-2006 04:49 PM
yast segmentation fault, system freezing - nvidia driver at fault? BaltikaTroika SUSE / openSUSE 2 12-02-2005 09:34 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 12:22 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration