Threading Segmentation fault

Hello All,

I am getting segmentation fault after the following lien when I try to run my datagram socket server program using threads:

    if\(\(n= recvfrom\(rec, buf, 1024, 0, \(struct sockaddr *\)&from_addr, &Size\)\) < 0\)

I am not able to figure out what exactly is causing the problem.
Would be glad if anyone can help me figure it out!

Following is my server code:

#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<netdb.h>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
#include<errno.h>
#include<pthread.h>

void *Recv_Handle(void *);

int main(int argc, char *argv[])
{
    int length;
    pthread_t thread;
    struct sockaddr_in receive_addr, send_addr, addr;
    int sendSOCKET, receiveSOCKET;
    int rc;
    printf("hey1");
    //receiving stuff
    if((receiveSOCKET = socket(AF_INET, SOCK_DGRAM, 0))<0)
    {
        error("Socket");
        exit(1);
    }
    printf("hello2");

    receive_addr.sin_family = AF_INET;
    receive_addr.sin_port = htons(5000);
    receive_addr.sin_addr.s_addr = INADDR_ANY;// local ip address
    bzero(&receive_addr, length);
    printf("hello 3");

    length = sizeof(receive_addr);
    if((bind(receiveSOCKET, (struct sockaddr *)&receive_addr, length)) <0)
    {
        error("unable to bind");
        exit(1);
    }
    //creat6e a thread to handle the receiving stufff
    rc = pthread_create(&thread, NULL, Recv_Handle, (void *)&receiveSOCKET);
    printf("hello3");    
        
close(receiveSOCKET);
pthread_exit(NULL);
}

void *Recv_Handle(void *received)
{
    int rec;
    int n;
    char buf[1024];
    printf("hello 4");    
    rec = *(int *)received;
    struct sockaddr_in from_addr;
    int Size;
    printf("hello 6");
    while(1)
    {
        Size = sizeof(from_addr);
        printf("hello 7");
        if((n= recvfrom(rec, buf, 1024, 0, (struct sockaddr *)&from_addr, &Size)) < 0)
        {
            error("recvfrom");
            exit(1);
        }
        printf("hello 8");
        if((n = sendto(rec, "got ur message\n", 17, 0, (struct sockaddr *)&from_addr, sizeof(struct sockaddr))) <0)
        {
        
        error("sendto");
        exit(1);
        }
    printf("hello 9");
    }
    pthread_exit(NULL);
}

        

Size should be a socklen_t.

I also don't see that main() is waiting for the receiving thread to finish... It should. You can't create a thread and quit the same way you can fork a process and quit because when main's thread quits, the entire process is gone.

Try pthread_join() to wait for the thread to end.

yes, it works with with pthread_join and changed my Size type to socklen_t:)

thanks a lotttttttttttt to everyone for inputs:):slight_smile:

actually it dosen't work properly:(..................I'm getting SIGSEGV, after segmentation fault:(..............even thought I joined the thread!

Any idea where the segfault happens? compile with -ggdb, and run with 'gdb ./filename', start it with 'run' inside gdb, then 'bt f' after it crashes to see a backtrace.

I'm getting an error:

"no symbol table info avalaible" : no idea what it is:(

It means you didn't compile it with the -ggdb flag.

Hello,

I didn't performed a deep analysis of your code, but I might shed some lights on the problem you're facing.

Yes, generally speaking your are correct. But notice here that main() calls pthread_exit(). In this case, the program will happily continue to perform until the thread Recv_Handle ceases to exit (assuming that the process only have these two threads). Detailed explanations about the main thread semantic can be found here: The main thread.

However I see a fundamental flaw: the way the receivedSocket is passed to the Recv_Handle thread. In the original posted code, you have a race condition. Indeed receivedSocket is a local variable stored on the main's stack. However, when the main() executes the pthread_exit(), receivedSocket becomes then undefined (indeed, the stack is usually located on a memory that is freed upon pthread_exit). When Recv_Handle thread accesses this variable, possibly main has already executed pthread_exit(). This can happen, because of the asynchronous nature of pthread_create(). At this point, all bets are off and you get a SIGSEGV.

The following article explains you how to pass (correctly) arguments between threads: Pthreads arguments passing.

This is may provide a help, but nevertheless the program remains incorrect because of the way the argument is passed, as explained here: Joinable and Detached Threads.

Besides that, in the original code, you are closing the recvSocket... recvfrom() in Recv_Handle thread should fail. If I find some times tomorrow, I'll review your code thoroughly.

HTH,
Lo�c.

Hello,

FYI- The posted program seems to work correctly if you fix the argument passing and don't close the recvSocket.

Cheers,
Lo�c.