启动新线程后的Segfault
我正在编写一个股票市场系统,它使用多个线程来处理收到的订单.
该项目进展顺利,直到我再添加一个帖子.当我启动所述线程我的程序段错误.通过无效的内存读取在上述线程中生成段错误. 只有在使用优化-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产生段错误的行是void * limitWorker(void * arg){ 还有一些更多的信息是使用gcc 4.6.1编译的,当使用gcc 4.1.2时,程序不会出现段错误,即使它已经过优化,尽管它的性能要差得多. 当使用clang编译程序时,它在优化时也不会出现段错误. 题 我犯了错误吗?这是一个gcc bug吗?我应该遵循什么样的行动? 如果你想查看代码,github页面是https://github.com/spapageo/Stock-Market-Real-Time-System/ 有问题的代码在文件marketSim.c和limit.c中 编辑:Valgrind指定无效读取发生在第4行.第4行是函数的“头部”.我不知道编译器内部,所以我天真的想法是,这个论点是错误的.但是在segfault参数之后使用gdb时,由于程序已经优化,因此根据gdb进行了优化.所以我不认为那是罪魁祸首. 解决方法
如果要编译64位系统,则0x1c是order结构中price1字段的偏移量.这意味着当故障发生时,lsl-> HEAD和lbl-> HEAD中的任何一个(或两个)都是NULL指针.
请注意,因为你的limitWorker()函数在llPairDelete()函数之外不包含线程同步,所以它是不正确的,并且编译器可能不会在每次执行循环时重新加载这些值.您应该使用使用互斥锁来保护链接列表,即使在只读路径中也是如此. 此外,您的lsl和lbl变量是多重定义的.你应该在limit.h中将它们声明为extern,并在limit.c中定义它们而不使用extern. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |