Could anyone please help me in finding out the reason behind segmentation fault. This program is working fine as long as the command line input is as follows:
./test -r 300 -w 3 -s 100 (gives desired o/p)
./test -r 100 -w 3 -s 200 (gives desired o/p)
./test -r 10 -w 3 -s 10 (gives desired o/p)
But at the same time this program fails the moment I am trying to give following command line input
./test -r 3 -w 4 -s 100 (seg fault)
./test -r 1 -w 4 -s 10 (seg fault)
I have tried my level best to resolve this and to find out the reason behind failing. But could not able to find the solution. While using dbx I came to know the point where it's failing but unfortunately I don't know how to resolve it.
I have mentioned the dbx output below to have a look at it and it may save your time to help me in solving this problem.
midibm14:subh:/home/users/subh/demo #dbx test
Type 'help' for help.
reading symbolic information ...
(dbx) stop in main
[1] stop in main
(dbx) r -r 300 -w 3 -s 100
[1] stopped in main at line 14 ($t1)
14 parse_args(argc, argv);
(dbx) c
test: Shared Memory Test Program
Number of writers thread = 3
Number of readers thread = 300
Shared Memory Size in Bytes = 100
execution completed
(dbx) q
midibm14:subh:/home/users/subh/demo #dbx test
Type 'help' for help.
reading symbolic information ...
(dbx) stop in main
[1] stop in main
(dbx) r -r 1 -w 4 -s 100
[1] stopped in main at line 14 ($t1)
14 parse_args(argc, argv);
(dbx) cont
test: Shared Memory Test Program
Number of writers thread = 4
Number of readers thread = 1
Shared Memory Size in Bytes = 100
Shmat Failed Here *** : Shared Memory Attach Error : Too many open files
execution completed
(dbx)
It's failing when I tried to increase the "-w option" in the 2nd execution.
Let me summarise the problem once again. I can run this program with the writer thread ("-w option") less than or equal to 3. But I can't run this program with the writer thread ("-w option") 4 or more.
May I request you to look into the problem and please provide me the solution.
Code:
/*********************************************/
/****************** head.h *********************/
/*********************************************/
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/limits.h>
#include <sys/signal.h>
/********************* User Defined Data ***************/
#define MAX_THREAD_NUMBER 30000
#define MAX_WRITER_NUMBER 100
#define MAX_READER_NUMBER 999
#define DEFAULT_NUM_READERS 2
#define DEFAULT_NUM_WRITERS 2
#define SHMEM_MODE (SHM_R | SHM_W)
/*#define DEFAULT_SHMEM_SIZE 2000000000*/
#define DEFAULT_SHMEM_SIZE 200
#define MB (1024*1024)
#define MAX_SHMEM_NUMBER 100
#define USAGE "\nUsage: %s [-r num_readers] [-w num_writers] [-s shmem_size]\n
\n" \
"\t-r num_readers number of reader thread to create\n" \
"\t-w num_writers number of writer thread to create\n" \
"\t-s buffer_size size of shmem segments in bytes\n" \
"\t must be less than 256MB\n\n"
/************ Global Functions ****************/
void parse_args(int , char **);
void *reader(void *);
void *writer(void *);
void error(const char *, int);
void release();
/*int sys_error(const char *, int);*/
/************ Global Variables ****************/
pthread_t *writer_th;
pthread_t *reader_th;
int thread_hold[MAX_WRITER_NUMBER];
pthread_mutex_t cond_mutex[MAX_WRITER_NUMBER];
pthread_mutex_t mutex_r[MAX_WRITER_NUMBER];
pthread_cond_t cond_var[MAX_WRITER_NUMBER];
int *read_count[MAX_WRITER_NUMBER];
char *shmptr[MAX_READER_NUMBER];
unsigned long *checksum[MAX_WRITER_NUMBER];
unsigned long cksum[MAX_WRITER_NUMBER];
int shmem_size = DEFAULT_SHMEM_SIZE;
pid_t parent_pid;
int num_readers = DEFAULT_NUM_READERS;
int buffer_size = DEFAULT_SHMEM_SIZE;
int num_writers = DEFAULT_NUM_WRITERS;
int shmid[MAX_THREAD_NUMBER + MAX_WRITER_NUMBER];
/*********************************************/
/****************** test.c *********************/
/*********************************************/
#include "head.h"
int main(int argc, char **argv)
{
pthread_attr_t newattr;
int i, j, k;
size_t Size;
unsigned long *ulptr;
parse_args(argc, argv);
printf("%s: Shared Memory Test Program\n\n", *argv);
printf("\tNumber of writers thread = %d\n", num_writers);
printf("\tNumber of readers thread = %d\n", num_readers);
printf("\tShared Memory Size in Bytes = %d\n", buffer_size);
printf("\n");
for(i = 0; i < num_writers; i++) {
j = i * 3;
Size = sizeof(int);
if((shmid[j] = shmget(IPC_PRIVATE, Size, SHMEM_MODE)) < 0)
perror("Shmget Error");
if((long)(read_count[i] = (int *) shmat(shmid[j], 0, 0)) == -1)
perror("Shmat Error");
*(read_count[i]) = 0;
j++;
Size = sizeof(unsigned long) * num_readers;
if((shmid[j] = shmget(IPC_PRIVATE, Size, SHMEM_MODE)) < 0)
perror("Checksum Shmget Failed");
if((long)(checksum[i] = (unsigned long *) \
shmat(shmid[j], 0, 0)) == -1)
perror("Shmat : Shared Memory Attach Error ");
ulptr = checksum[i];
for(k = 0; k < num_readers; k++)
{
*ulptr = 0;
ulptr++;
}
Size = buffer_size;
j++;
if((shmid[j] = shmget(IPC_PRIVATE, Size, SHMEM_MODE)) < 0)
perror("Shmptr Shmget Failed");
if((long)(shmptr[i] = shmat(shmid[j], 0, 0)) == -1)
perror("Shmat Failed Here *** : Shared Memory Attach Error ");
}
}
void parse_args(int argc, char **argv)
{
int i;
int errflag = 0;
char *program_name = *argv;
extern char *optarg;
while((i = getopt(argc, argv, "r:s:w:?")) != EOF) {
switch (i) {
case 'r':
num_readers = atoi(optarg);
break;
case 's':
buffer_size = atoi(optarg);
break;
case 'w':
num_writers = atoi(optarg);
break;
case '?':
errflag++;
break;
}
}
if(num_writers >= MAX_WRITER_NUMBER) {
errflag++;
fprintf(stderr, "ERROR: num_writers must be less\
than %d\n", MAX_WRITER_NUMBER);
}
if(num_readers >= MAX_READER_NUMBER) {
errflag++;
fprintf(stderr, "ERROR: num_readers must be less\
than %d\n", MAX_READER_NUMBER);
}
i = num_readers * num_writers;
if(i >= MAX_THREAD_NUMBER) {
errflag++;
fprintf(stderr, "ERROR: maximun threads number\
must be less than %d\n", MAX_THREAD_NUMBER);
}
if(errflag) {
fprintf(stderr, USAGE, program_name);
exit (2);
}
}