LinuxQuestions.org
Help answer threads with 0 replies.
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 09-19-2008, 08:04 AM   #1
kumars
LQ Newbie
 
Registered: Sep 2008
Posts: 4

Rep: Reputation: 0
Thread Porg in C (seg Fault)


Could you 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.

/********************************************/
/****************** 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);
}
}
 
Old 09-19-2008, 08:31 AM   #2
CRC123
Member
 
Registered: Aug 2008
Distribution: opensuse, RHEL
Posts: 374
Blog Entries: 1

Rep: Reputation: 32
Please use 'CODE' tags when posting code.

Apparently your code is failing on this call:
Code:
if((long)(shmptr[i] = shmat(shmid[j], 0, 0)) == -1)
perror("Shmat Failed Here *** : Shared Memory Attach Error ");
What are i and j at this point?
 
Old 09-19-2008, 11:13 AM   #3
kumars
LQ Newbie
 
Registered: Sep 2008
Posts: 4

Original Poster
Rep: Reputation: 0
Thread Prog in C (seg Fault)

Actually I have sent you a piece of code. Here is the complete program to have a look at it.

I am able to run this program successfully by giving following input

./main -r 300 -w 3 -s 100
./main -r 100 -w 2 -s 100
./main -r 30 -w 3 -s 100


But I am not able to run the program as follows(It gives me the segmentation fault) and the reason is not known to me.
./main -r 1 -w 4 -s 100

I don't know why it fails, if I give "-w option" (4 or more). It works if "-w option" is less than or equal to 3.

It'll be of great help if you can look at the whole program and let me know where I am doing wrong. If possible do also provide me the solution as I have no clue to solve it.



Code:

/****************************************************/
/********************** header.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/signal.h>


/********************* User Defined Data ***************/

#define MAX_THREAD_NUMBER       5000
#define MAX_WRITER_NUMBER       100
#define MAX_READER_NUMBER       400
#define DEFAULT_NUM_READERS     2
#define DEFAULT_NUM_WRITERS     2
#define SHMEM_MODE              (SHM_R | SHM_W)
#define DEFAULT_SHMEM_SIZE      20000
#define MB                      (1024*1024)
#define MAX_SHMEM_NUMBER        11



#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 ****************/

int  parse_args(int , char **);
int *reader(void *);
int *writer(void *);
int  error(const char *, int);
int  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_WRITER_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];



/****************************************************/
/********************** main.c **********************/
/****************************************************/

#include "header.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 Failed : 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 ");

        }


        writer_th = (pthread_t *) malloc((size_t) (num_writers \
                                                   * sizeof(pthread_t)));
        reader_th = (pthread_t *) malloc((size_t) (num_writers \
                                     * num_readers * sizeof(pthread_t)));

        for(i = 0; i < num_writers; i++) {

        if(pthread_mutex_init(&mutex_r[i] , (pthread_mutexattr_t *)NULL) != 0)
                perror("Can't Initialise Mutex");


        if(pthread_mutex_init (&cond_mutex[i], (pthread_mutexattr_t *)NULL)!=0)
                perror("Can't Initialize Cond_Mutex");


        if(pthread_cond_init (&cond_var[i], (pthread_condattr_t *)NULL)!=0)
                perror("Cond_Var Failed");


        thread_hold[i] = 1;
        }
        if(pthread_attr_init(&newattr))
               perror("Attr_Init Failed");


        if(pthread_attr_setdetachstate(&newattr, PTHREAD_CREATE_UNDETACHED))
                perror("Attr_Setdetachstate Failed");



        for(i = 0; i < num_writers; i++)
        {


                if(pthread_create(&writer_th[i], &newattr, writer, \
                                                        (void *) (long)i))
                        perror("Writer Failed");

                k = i * num_readers;


                for(j = k; j < (k + num_readers) ; j++)
                {
                        if(pthread_create(&reader_th[j], &newattr, reader,\
                                                        (void *) (long)j))

                        perror("Reader Failed");
                }
        }


        for(i = 0; i < num_writers; i++)
        {
               if(pthread_join(writer_th[i], NULL)) {
                        printf("writer_th: pthread_join return: %d\n",i);

                        perror("Pthread_join Bad Status");
                }

                k = i * num_readers;


                for(j = k; j < (k + num_readers) ; j++)
                {
                        if(pthread_join(reader_th[j], NULL)) {
                        perror("Pthread_join Bad Status");
                        }
                }
        }

        for(i = 0; i < num_writers; i++)
        {
                ulptr = checksum[i];
                for(j = 0; j < num_readers; j++) {

                        if(cksum[i] != *ulptr )
                                error("checksums do not match", __LINE__);

                }
        }


        printf("\n\tMain: Readers calculated segment successfully\n");

        release();
        printf("\nsuccessful!\n");

        return(0);
}


/****************************************************/
/******************** reader.c **********************/
/****************************************************/

#include "header.h"



void *reader(void *parm)
{
        int num_p = (int) (long)parm;
        unsigned long cksum_r = 0;
        int     i, num_r, num_w;
        char    *ptr;
        unsigned long *ulptr_r;


        num_r = num_p % num_readers;
        num_w = num_p - num_r;
        num_w = num_w / num_readers;
        ptr = shmptr[num_w];
        ulptr_r = checksum[num_w];

        if(pthread_mutex_lock (&cond_mutex[num_w]))
                perror("Can't Take Cond Lock");

        while(thread_hold[num_w])
        {
                if(pthread_cond_wait(&cond_var[num_w], &cond_mutex[num_w]))
                        perror("cond_wait failed");
        }
        if(pthread_mutex_unlock(&cond_mutex[num_w]))
                perror("Release cond Lock Failed");

        if(pthread_mutex_lock(&mutex_r[num_w]))
                perror("Can't take read Lock");

        (*(read_count [num_w]))++;

        if(pthread_mutex_unlock(&mutex_r[num_w]))
                perror("Can't Release Read Lock");

        for(i = 0; i < buffer_size; i++)
                cksum_r += *ptr++;

        if(pthread_mutex_lock(&mutex_r[num_w]))
                perror("Can't Take Read Lock");

        (*(read_count[num_w]))--;

        if(pthread_mutex_unlock(&mutex_r[num_w]))
                perror("Can't Release 1 Read Lock");


        *ulptr_r = cksum_r;

        printf("\tReader (%d) of Writer (%d): checksum %04ld\n",\
                                                num_r,num_w,cksum_r);

        return NULL;
}


/****************************************************/
/******************** writer.c **********************/
/****************************************************/


#include "header.h"



void *writer(void *parm)
{
        int num_w = (int) (long)parm;
        unsigned long cksum_w = 0;
        char  data = 0;
        char  *ptr;
        int count = 0;


        data = num_w;

        for(ptr = shmptr[num_w]; ptr < (shmptr[num_w]+buffer_size); ptr++) {
                *ptr = data++;
                cksum_w += *ptr;

        }

        /*perror("Writer: Writer failed here 0: ");*/

        if(pthread_mutex_lock(&cond_mutex[num_w]))
                perror("Mutex_lock Failed");


        thread_hold[num_w] = 0;


        if(pthread_cond_broadcast(&cond_var[num_w]))
                perror("cond_signal Failed");


        if(pthread_mutex_unlock(&cond_mutex[num_w]))
                perror("Mutex_unlock Failed");



        cksum[num_w] = cksum_w;
        printf("\n\tWriter (%d): shared memory checksum %04ld\n", \
                                                         num_w, cksum_w);


        return NULL;
}


/****************************************************/
/******************** parseargs.c *******************/
/****************************************************/

#include "header.h"


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


int release()
{
        int i, j;

        for(i = 0; i < num_writers; i++) {
        if(pthread_mutex_destroy(&cond_mutex[i]) != 0)
                perror("Can't destroy cond_mutex");

        if(pthread_mutex_destroy(&mutex_r[i]) != 0)
                perror("Can't destroy mutex_r");
        }


        for(i = 0; i < num_writers; i++) {

        j = i * 3;
        if(shmctl(shmid[j], IPC_RMID, 0) < 0)
                perror("Read_count shmctl Failed");
        j++;
        if(shmctl(shmid[j], IPC_RMID, 0) < 0)
                perror("checksum shmctl failed");
        j++;
        if(shmctl(shmid[j], IPC_RMID, 0) < 0)
                perror("shmptr shmctl failed");

        }
}



int sys_error(const char *msg, int line)
{
        char syserr_msg [256];

        sprintf(syserr_msg, "%s: %s\n", msg, strerror (errno));
        error(syserr_msg, line);
}

int error(const char *msg, int line)
{
        fprintf(stderr, "ERROR [line: %d] %s\n", line, msg);
        if(line>= 260)
        release();
        exit(-1);
}
 
  


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
seg fault / mem fault - in cron, but works in shell? kauaikat Red Hat 1 04-29-2008 04:24 PM
seg fault / mem fault - in cron, but works in shell? kauaikat Linux - Software 1 04-29-2008 08:21 AM
seg fault vm_devadas Linux - Enterprise 1 12-05-2006 02:28 PM
C seg fault drigz Programming 5 10-01-2004 03:35 PM

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

All times are GMT -5. The time now is 05:56 AM.

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