Thread parameter in ANSI C makes a segmentation fault


 
Thread Tools Search this Thread
Top Forums Programming Thread parameter in ANSI C makes a segmentation fault
# 8  
Old 05-05-2011
Quote:
Originally Posted by sehang
So that means using -O3 in multi-threading is a bad idea?
No, I didn't say that. -O3 may tend to expose latent bugs in your program, multithreaded or not.
# 9  
Old 05-05-2011
Quote:
Originally Posted by sehang
Thanks. I try it now. However, I can run the program under the text mode only since our system doesn't have a GUI. Is valgrind able to work in text mode?
Yes, valgrind work in text mode. Which processor architecture are you using?

Could you run the following command under gdb:
Code:
thread apply all bt

Besides that, I am a bit surprised by the "signal 6". You mentioned SIGSEGV, and I believe that would be always 11 on Linux? Perhaps you are looking at the wrong place...

Cheers, Loïc
# 10  
Old 05-06-2011
Quote:
Originally Posted by Loic Domaigne
Yes, valgrind work in text mode. Which processor architecture are you using?

Could you run the following command under gdb:
Code:
thread apply all bt

Besides that, I am a bit surprised by the "signal 6". You mentioned SIGSEGV, and I believe that would be always 11 on Linux? Perhaps you are looking at the wrong place...

Cheers, Loïc
Yes, I may looking at a wrong place... I will try it again now.

But signal = SIGABRT (6), how can I mask this signal within a thread?
# 11  
Old 05-06-2011
Bug

Quote:
Originally Posted by sehang
The creation of thread.
Code:
void Client_Constructor ( const char* IPAddr ) {
    pthread_t tid; 
    pthread_attr_t rx;  

    /* Create separate memory for client argument */
    struct ThreadArgs *threadArgs;
    if ( ( threadArgs = ( struct ThreadArgs* ) malloc( sizeof( struct ThreadArgs ) ) ) == NULL )
        exit( -1 );
    threadArgs->pos = 111;

    pthread_rwlock_wrlock( &rwlock );
    node = ....;
    if ( node->state == DISCONNECTED ) {  <-node requires a r/w lock.
        pthread_attr_init( &rx );
        pthread_attr_setdetachstate( &rx, PTHREAD_CREATE_DETACHED );
        pthread_create( &tid, &rx, THREAD_BODY, ( void* )threadArgs );
    }
    pthread_rwlock_unlock( &rwlock );
}

Thread body
Code:
static void* THREAD_BODY ( void* v ) {
    int sockfd;
    char IPStr[ 16 ];
    int index = ( ( struct ThreadArgs* ) v )->pos; free( v ); <-segmentation fault here
.....
}

These code is so strange, when I run the program more than few hours, then a segmentation fault comes. I also dump the log and use gdb to analyze it, the information is shown below
Code:
Program terminated with signal 6, Aborted.
#0  0xb7de1a16 in ?? () from /lib/libc.so.6
(gdb) where
#0  0xb7de1a16 in ?? () from /lib/libc.so.6
#1  0xb7de3318 in ?? () from /lib/libc.so.6
#2  0xb7e1cfdd in fputws () from /lib/libc.so.6
#3  0xb7e1d114 in ?? () from /lib/libc.so.6
#4  0xb7e287ba in realloc () from /lib/libc.so.6
#5  0xb7e28040 in ?? () from /lib/libc.so.6
#6  0xb7e28339 in ?? () from /lib/libc.so.6
#7  0xb7e2476b in ?? () from /lib/libc.so.6
#8  0x0805e945 in THREAD_BODY (v=0x1838b9b0) at Client.c:167
#9  0xb7efffc0 in pthread_create@@GLIBC_2.1 () from /lib/libpthread.so.0
#10 0xb7e8497e in ?? () from /lib/libc.so.6

It anyone give me some suggestions? Is it related to pthread_rwlock?
Hi,

run it on gdb to print the value(address) of v where you allocate it and where you free it to see if its getting corrupted by some other thread. So far what you have pasted looks okay to me. One suggestion in here would be to initialize v=NULL after you free in case it gets freed twice in the code.

Thanks and Regards,
Gaurav.
# 12  
Old 05-06-2011
Quote:
Originally Posted by sehang
Yes, I may looking at a wrong place... I will try it again now.

But signal = SIGABRT (6), how can I mask this signal within a thread?
As you would do for any other signal in multi-threaded program:
- mask the signal in all thread using pthread_sigblock()
- dedicated a thread that wait synchronously on the signal to occur.

See example from: SUSv3 - pthread_sigmask()

By the way, SIGABRT is usually caused by abort(). It could be a good idea to check if your program triggers abort() at some places.

HTH, Loïc
# 13  
Old 05-08-2011
Finally, I found the problem, it is caused by use of select().
And the error message is "too many open file descriptors"; Besides, I used "netstat -an" to check the network status, I saw a lot of ESTABLISHED connections and can't release.
But I always use a close() after the descriptor completed. Why this problem happens in my program?


I post the source code of client and server side.
Client.c
Code:
  int Close ( int fd, const char* filename, int line ) {
      int ret;
      if ( ( ret = close( fd ) ) == -1 ) {
  #ifdef LOGGING_ENABLE
          sprintf( log, "%s(%d) -> close() failed: %s", filename, line, strerror( errno ) );
          Log( log );
  #endif
      }
      return ret;
  }
  
  void Client_CloseConnection ( int sockfd ) {
      Close( sockfd, __FILE__, __LINE__ );
  }
  
static void* CLIENT_THREAD ( void* v ) {
    int sockfd;                                 /* Socket descriptor. */
    int index = *( int* )v; /*free( v );*/          /* Position in the @PeerList. */
    ...

    /* Assume the connection is OK by default. */
    Pthread_rwlock_wrlock( &rwlock, __FILE__, __LINE__ );
    node->state = CONNECTED;
    Pthread_rwlock_unlock( &rwlock, __FILE__, __LINE__ );

    while ( 1 ) {
        /* Wait until messages come. */
        Pthread_mutex_lock( &node->mutex, __FILE__, __LINE__ );
        Pthread_rwlock_rdlock( &rwlock, __FILE__, __LINE__ );
        tmp = Queue4SendData_GetCount( & ( node->Q ) );
        Pthread_rwlock_unlock( &rwlock, __FILE__, __LINE__ );
        while ( tmp == 0 ) {
            Pthread_cond_wait( &node->isEmpty, &node->mutex, __FILE__, __LINE__ );
            Pthread_rwlock_rdlock( &rwlock, __FILE__, __LINE__ );
            tmp = Queue4SendData_GetCount( & ( node->Q ) );
            Pthread_rwlock_unlock( &rwlock, __FILE__, __LINE__ );
            if ( tmp == 0 )
                continue;
            break;
        }

        //Get the message which going to send
        Pthread_rwlock_wrlock( &rwlock, __FILE__, __LINE__ );
        data = Queue4SendData_Pop( & ( node->Q ) );
        Pthread_rwlock_unlock( &rwlock, __FILE__, __LINE__ );

        /* Let Producer continue insert items. */
        Pthread_cond_signal( &node->isFull, __FILE__, __LINE__ );
        Pthread_mutex_unlock( &node->mutex, __FILE__, __LINE__ );

        tmp = 1;        /* Status flag (0 = error, 1 = OK). */
        if ( Client_TestConnection( &sockfd, IPStr ) ) {
            Writen( sockfd, data.send_buf, strlen( data.send_buf ), __FILE__, __LINE__ );
            if ( ( n = Readline( index, sockfd, recvline, TCP_MAXLINE ) ) <= 0 ) {
#ifdef LOGGING_ENABLE
                if ( n == 0 )
                    sprintf( log, "%s(%d) -> Server %s terminated prematurely", __FILE__, __LINE__, IPStr );
                else
                    sprintf( log, "%s(%d) -> Readline() on %s failed: %s", __FILE__, __LINE__, IPStr, strerror( errno ) );
                Log( log );
#endif
                tmp = 0;
            } else {
                handler = data.handler;
                handler( recvline, IPStr );     /* Call packet handler. */
            }
        } else {
            tmp = 0;
        }

        //DON'T FORGET THESE CODES.
        Client_CloseConnection( sockfd ); <- close is called here!!
        if ( tmp == 0 )
            break;
    }
    return NULL;
}

This function used to create a connection with a server; in my project, a client needs to connect few servers at the same time.
void Client_Constructor ( const char* IPAddr ) {
    int status;
    pthread_t tid;      /* Thread ID. */
    pthread_attr_t rx;  /* Parameter of thread. */
    int pos = Client_GetPosition( IPAddr );
    struct PeerInfo* node = &PeerList[ pos ];
    
    Pthread_rwlock_rdlock( &rwlock, __FILE__, __LINE__ );
    status = node->state;
    Pthread_rwlock_unlock( &rwlock, __FILE__, __LINE__ );
    
    if ( status == DISCONNECTED ) {   //Server is offline, then connect it!
        Pthread_rwlock_wrlock( &rwlock, __FILE__, __LINE__ );
        strcpy( node->IPStr, IPAddr ); 
        Queue4SendData_Init( &( node->Q ), SEND_QUEUE );
        node->state = CONNECTING;                       
        Pthread_rwlock_unlock( &rwlock, __FILE__, __LINE__ );
        Pthread_attr_init( &rx, __FILE__, __LINE__ ); 
        Pthread_attr_setdetachstate( &rx, PTHREAD_CREATE_DETACHED, __FILE__, __LINE__ );

        Pthread_rwlock_wrlock( &tbRwlock, __FILE__, __LINE__ );
        if ( threadBufPos >= 1024 )
            threadBufPos = 0;
        threadBuf[ threadBufPos ] = pos;
        Pthread_create( &tid, &rx, CLIENT_THREAD, ( void* )&( threadBuf[ threadBufPos ] ), __FILE__, __LINE__ );
        threadBufPos++;
        Pthread_rwlock_unlock( &tbRwlock, __FILE__, __LINE__ );
    }
}

Send messages to a server, IPAddr is the IP address of server.
void Client_Pend ( const char* IPAddr, struct SendDataStruct *data ) {
    struct SendDataStruct local;
    struct PeerInfo* node = &PeerList[ Client_GetPosition( IPAddr ) ];
    enum TCPState TCPStatus;
    int qSize;
    Pthread_rwlock_rdlock( &rwlock, __FILE__, __LINE__ );
    TCPStatus = node->state;                        /* Recent TCP status of the connection. */
    Pthread_rwlock_unlock( &rwlock, __FILE__, __LINE__ );
    
    if ( TCPStatus == CONNECTED ) {
        /* Blocking if the queue is full. */
        Pthread_mutex_lock( &node->mutex, __FILE__, __LINE__ );
        Pthread_rwlock_rdlock( &rwlock, __FILE__, __LINE__ );
        qSize = Queue4SendData_GetCount( & ( node->Q ) );
        Pthread_rwlock_unlock( &rwlock, __FILE__, __LINE__ );
        while ( SEND_QUEUE <= qSize ) {
            Pthread_cond_wait( &node->isFull, &node->mutex, __FILE__, __LINE__ );
            Pthread_rwlock_rdlock( &rwlock, __FILE__, __LINE__ );
            qSize = Queue4SendData_GetCount( & ( node->Q ) );
            Pthread_rwlock_unlock( &rwlock, __FILE__, __LINE__ );
            if ( SEND_QUEUE <= qSize )
                continue;   /* If the Queue is full, then blocking. */
            break;
        }

        Pthread_rwlock_wrlock( &rwlock, __FILE__, __LINE__ );
        local.handler = data->handler;             /* Clone packet handler. */
        strcpy( local.send_buf, data->send_buf );  /* Clone message to temporary array. */
        if ( Queue4SendData_Insert( & ( node->Q ), local ) == -1 ) {
#ifdef LOGGING_ENABLE
            sprintf( log, "%s(%d) -> Queue is full on client %s", __FILE__, __LINE__, node->IPStr );
            Log( log );
#endif
            exit( -1 );
        } else {
        }
        Pthread_rwlock_unlock( &rwlock, __FILE__, __LINE__ );

        /* Let the consumer read the inserted item. */
        Pthread_cond_signal( &node->isEmpty, __FILE__, __LINE__ );
        Pthread_mutex_unlock( &node->mutex, __FILE__, __LINE__ );
    } else if ( TCPStatus == DISCONNECTED ) {
        Client_Constructor( node->IPStr );
    }
}

Server.c
Code:
void Server_Constructor () {
    ssize_t n;
    int i, maxi, maxfd, listenfd, connfd, sockfd;
    int nready, client[ FD_SETSIZE ];
    fd_set rset, allset;
    char buf[ TCP_MAXLINE ];
    struct sockaddr_in cliaddr, srvAddr;
    socklen_t clilen;
    TIMER t = 0;

    if ( ( listenfd = Socket( AF_INET, SOCK_STREAM, 0, __FILE__, __LINE__ ) ) == -1 )
        return; /* Fail to create a socket. */
    i = 1;
    Setsockopt( listenfd, SOL_SOCKET, SO_REUSEADDR, &i, sizeof( int ), __FILE__, __LINE__ );    /* Reuse the socket. */

    /* Initiate server's address. */
    bzero( &srvAddr, sizeof( srvAddr ) );
    srvAddr.sin_family      = AF_INET;
    srvAddr.sin_addr.s_addr = htonl( INADDR_ANY );
    srvAddr.sin_port        = htons( TCP_PORT );

    if ( Bind( listenfd, ( struct sockaddr* )&srvAddr, sizeof( srvAddr ), __FILE__, __LINE__ ) == -1 )
        return; /* Fail to bind the socket. */
    if ( Listen( listenfd, TCP_MAX_PENGING, __FILE__, __LINE__ ) == -1 )
        return; /* Fail to listen to the socket. */

    /* Initiate select. */
    maxfd = listenfd;   /* Initialize. */
    maxi  = -1;         /* Index into client[] array. */
    for ( i = 0; i < FD_SETSIZE; client[ i ] = -1, i++ );   /* -1 indicates available entry. */
    FD_ZERO( &allset );
    FD_SET( listenfd, &allset );

    for ( ; ; ) {
        t = time2MS();
        rset = allset;      /* Structure assignment. */
        nready = Select( maxfd + 1, &rset, NULL, NULL, NULL, __FILE__, __LINE__ );
        if ( FD_ISSET( listenfd, &rset ) ) {    /* New client connection. */
            clilen = sizeof( cliaddr );
            if ( ( connfd = Accept( listenfd, ( struct sockaddr* )&cliaddr, &clilen, __FILE__, __LINE__ ) ) == -1 )
                continue;


            for ( i = 0; i < FD_SETSIZE ; i++ )
                if ( client[ i ] < 0 ) {
                    client[ i ] = connfd; /* save descriptor. */
                    break;
                }

            if ( i == FD_SETSIZE ) {
#ifdef LOGGING_ENABLE
                sprintf( buf, "%s(%d) -> Too many clients", __FILE__, __LINE__ );
                Log( buf );
#endif
                return;
            }

            FD_SET( connfd, &allset );              /* Add new descriptor to set. */
            if ( connfd > maxfd ) maxfd = connfd;   /* For select. */
            if ( i > maxi ) maxi = i;               /* Max index in client[] array. */
            if ( --nready <= 0 ) continue;          /* No more readable descriptors. */
        }

        /* Check all clients for data. */
        for ( i = 0; i <= maxi ; i++ ) {
            if ( ( sockfd = client[ i ] ) < 0 )
                continue;
            if ( FD_ISSET( sockfd, &rset ) ) {
                if ( readable_timeo( sockfd, 1 ) <= 0 ) {
                    printf( "UNABLE TO READ %d\n", sockfd );
                    exit( -1 );
                } else if ( ( n = Readline( sockfd, buf, TCP_MAXLINE ) ) <= 0 ) {  /* For connection closed by client. */
                    Close( sockfd, __FILE__, __LINE__ ); <- close is called here!!
                    FD_CLR( sockfd, &allset );
                    client[ i ] = -1;
                } else {
                    PacketHandler( sockfd, buf, n );
                }
                if ( --nready <= 0 )  break;    /* No more readable descriptors. */
            }
        }
    }
}

Errors
Code:
Server.c(271) -> accept() failed: Too many open files
...
/Client.c(332) -> close() failed: Bad file descriptor
...


Last edited by sehang; 05-08-2011 at 03:31 AM..
# 14  
Old 05-08-2011
Quote:
Finally, I found the problem, it is caused by use of select().
And the error message is "too many open file descriptors"; Besides, I used "netstat -an" to check the network status, I saw a lot of ESTABLISHED connections and can't release.
But I always use a close() after the descriptor completed. Why this problem happens in my program?
Without digging deeper in your code, the first thoughts that come to my mind:
- How many simultaneous client connection do you have?
- What are your ulimits?
Code:
$ ulimit -aS  // currently set
$ ulimit -aH  // hard limits

HTH, Loïc
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. Programming

C. To segmentation fault or not to segmentation fault, that is the question.

Oddities with gcc, 2.95.3 for the AMIGA and 4.2.1 for MY current OSX 10.14.1... I am creating a basic calculator for the AMIGA ADE *NIX emulator in C as it does not have one. Below are two very condensed snippets of which I have added the results inside the each code section. IMPORTANT!... (11 Replies)
Discussion started by: wisecracker
11 Replies

2. Programming

Segmentation fault

I keep getting this fault on a lot of the codes I write, I'm not exactly sure why so I'd really appreciate it if someone could explain the idea to me. For example this code #include <stdio.h> main() { unsigned long a=0; unsigned long b=0; int z; { printf("Enter two... (2 Replies)
Discussion started by: sizzler786
2 Replies

3. Programming

Using gdb, ignore beginning segmentation fault until reproduce environment segmentation fault

I use a binary name (ie polo) it gets some parameter , so for debugging normally i do this : i wrote script for watchdog my app (polo) and check every second if it's not running then start it , the problem is , if my app , remain in state of segmentation fault for a while (ie 15 ... (6 Replies)
Discussion started by: pooyair
6 Replies

4. UNIX for Advanced & Expert Users

segmentation fault with ps

What does this mean and why is this happening? $ ps -ef | grep ocular Segmentation fault (core dumped) $ ps -ef | grep ocular Segmentation fault (core dumped) $ ps aux | grep ocular Segmentation fault (core dumped) $ ps Segmentation fault (core dumped) $ pkill okular $ ps... (1 Reply)
Discussion started by: cokedude
1 Replies

5. Programming

Segmentation fault in C

i have this code int already_there(char *client_names, char *username) { int i; for(i = 0; i<NUM; i++) { printf("HERE\n"); if (strcmp(client_names, username)==0) return(1); } return(0); } and i get a segmentation fault, whats wrong here? (7 Replies)
Discussion started by: omega666
7 Replies

6. Programming

segmentation fault.

This code is causing a segmentation fault and I can't figure out why. I'm new to UNIX and I need to learn how to avoid this segmentation fault thing. Thank you so much. Thanks also for the great answers to my last post.:):b: int main() { mysqlpp::Connection conn(false); if... (3 Replies)
Discussion started by: sepoto
3 Replies

7. Programming

segmentation fault

If I do this. Assume struct life { char *nolife; } struct life **life; // malloc initialization & everything if(life->nolife == 0) Would I get error at life->nolife if it is equal to 0. wrong accession? (3 Replies)
Discussion started by: joey
3 Replies

8. AIX

Segmentation fault

Hi , During execution a backup binary i get following error "Program error 11 (Segmentation fault), saving core file in '/usr/datatools" Riyaz (2 Replies)
Discussion started by: rshaikh
2 Replies

9. Programming

segmentation fault

ive written my code in C for implementation of a simple lexical analyser using singly linked list hence am making use of dynamic allocation,but when run in linux it gives a segmentation fault is it cause of the malloc function that ive made use of????any suggestions as to what i could do??? thank... (8 Replies)
Discussion started by: rockgal
8 Replies

10. Programming

Hi! segmentation fault

I have written a program which takes a directory as command line arguments and displays all the dir and files in it. I don't know why I have a problem with the /etc directory.It displays all the directories and files untill it reaches a sub directory called peers which is in /etc/ppp/peers.the... (4 Replies)
Discussion started by: vijlak
4 Replies
Login or Register to Ask a Question