Spyros
Spyros

Reputation: 67

Segfault after launching a new thread

I am writing a stock market system that uses several threads to process the incoming orders.

The project was going fine until i added one more thread. When i launch the said thread my program segfaults. The segfault is generated in the above thread by an invalid memory read.

This segfault is generated only when the program is compiled with optimization -O2 and above.

After compiling the programming with debug info using -g3 and running valgrind using

valgrind ./marketSim

and get the following output about the segfault

==2524== Thread 5:
==2524== Invalid read of size 4
==2524==    at 0x402914: limitWorker (limit.c:4)
==2524==    by 0x4E33D5F: start_thread (in /lib/libpthread-2.14.so)
==2524==  Address 0x1c is not stack'd, malloc'd or (recently) free'd
==2524== 
==2524== 
==2524== Process terminating with default action of signal 11 (SIGSEGV)
==2524==  Access not within mapped region at address 0x1C
==2524==    at 0x402914: limitWorker (limit.c:4)
==2524==    by 0x4E33D5F: start_thread (in /lib/libpthread-2.14.so)

The thread is launched like this

pthread_t limit_thread;
pthread_create(&limit_thread, NULL, limitWorker, q);

q is variable which is also passed to other threads i initialize

the limitWorker code is as follows

void *limitWorker(void *arg){
    while(1){
        if ((!lsl->empty) && (!lbl->empty)) {
            if ((currentPriceX10 > lGetHead(lsl)->price1) && (currentPriceX10 < lGetHead(lbl)->price1)) {
                llPairDelete(lsl,lbl);
            }
        }
    }
    return NULL;
}

Line 4: The line which according to valgrind produces the segfault is void *limitWorker(void *arg){

Also some more info this is compiled using gcc 4.6.1, when using gcc 4.1.2 the program doesn't segfault, even when it is optimized although it's performance is much worse.

When the program is complied using clang it also doesn't segfault when optimized.

Question

Am i making a mistake?? Is it a gcc bug?? What course of action should i follow??

If you want to take a look at the code the github page is https://github.com/spapageo/Stock-Market-Real-Time-System/

The code in question is in file marketSim.c and limit.c

EDIT: Valgrind specifies that the invalid read happens at line 4. Line 4 is the "head" of the function. I don't know compiler internals, so my naive thought is that the argument is wrong. BUT while using gdb after the segfault the argument , because the program is optimized, is optimized out according to gdb. So i don't think that that is the culprit.

Upvotes: 3

Views: 962

Answers (1)

caf
caf

Reputation: 239011

If you are compiling for a 64 bit system, then 0x1c is the offset of the price1 field within the order struct. This implies that either (or both) of lsl->HEAD and lbl->HEAD are NULL pointers when the fault occurs.

Note that because your limitWorker() function includes no thread synchronisation outside of the llPairDelete() function, it is incorrect and the compiler may not be reloading those values on every execution of the loop. You should be using a using a mutex to protect the linked lists even in the read-only paths.

Additionally, your lsl and lbl variables are multiply defined. You should declare them as extern in limit.h, and define them without the extern in limit.c.

Upvotes: 7

Related Questions