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);
        }
}