Segfault после запуска новой темы - PullRequest
3 голосов
/ 21 июля 2011

Я пишу систему фондового рынка, которая использует несколько потоков для обработки входящих заказов.

Проект работал нормально, пока я не добавил еще одну ветку.Когда я запускаю указанный поток, моя программа работает с ошибками.Сегфоут генерируется в вышеуказанном потоке недопустимым чтением из памяти.

Этот сэгфоут генерируется только , когда программа компилируется с оптимизацией -O2 и выше.

Послескомпилировать программирование с отладочной информацией, используя -g3, и запустить valgrind, используя

valgrind ./marketSim

и получить следующий вывод о 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)

Поток запускается так:

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

q - это переменная, которая также передается в другие потоки, которые я инициализирую

код limitWorker выглядит следующим образом

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

Строка 4: Строка, которая в соответствии с valgrind создаетsegfault - void *limitWorker(void *arg){

Также некоторая дополнительная информация, которая скомпилирована с использованием gcc 4.6.1, при использовании gcc 4.1.2 программа не выполняет segfault, даже если она оптимизирована, хотя ее производительность намного хуже.

Когда программа выполняется с использованием clang, она также не вызывает segfault при оптимизации.

Вопрос

Я делаю ошибку?Это ошибка GCC ??Какой курс действий я должен следовать ??

Если вы хотите взглянуть на код, страница github будет https://github.com/spapageo/Stock-Market-Real-Time-System/

Код, о котором идет речь, находится в файле marketSim.c и limit.c

РЕДАКТИРОВАТЬ: Valgrind указывает, что недопустимое чтение происходит в строке 4. Строка 4 является «головой» функции.Я не знаю внутренностей компилятора, поэтому моя наивная мысль в том, что аргумент неверен. НО при использовании gdb после аргумента segfault, поскольку программа оптимизирована, is optimized out в соответствии с gdb.Так что я не думаю, что это виновник.

1 Ответ

7 голосов
/ 21 июля 2011

Если вы компилируете для 64-битной системы, то 0x1c - это смещение поля price1 в структуре order. Это означает, что либо (или оба) из lsl->HEAD и lbl->HEAD являются указателями NULL при возникновении ошибки.

Обратите внимание, что поскольку ваша функция limitWorker() не включает синхронизацию потоков вне функции llPairDelete(), она некорректна, и компилятор может не перезагружать эти значения при каждом выполнении цикла. Вы должны использовать мьютекс для защиты связанных списков даже в путях только для чтения .

Кроме того, переменные lsl и lbl определены несколько раз. Вы должны объявить их как extern в limit.h и определить их без extern в limit.c.

...