C 集成x86 FreeRTOS端口(pthreads)和辅助pthreads代码时出现无法解释的行为

C 集成x86 FreeRTOS端口(pthreads)和辅助pthreads代码时出现无法解释的行为,c,gdb,pthreads,valgrind,freertos,C,Gdb,Pthreads,Valgrind,Freertos,我不知道如何找出我的问题出在哪里 我试图将一个异步UDP处理程序合并到现有的FreeRTOS仿真器中,两者都是基于pthreads的。FreeRTOS实现本质上是pthreads的包装器,UDP处理程序生成一个FreeRTOS任务,然后为每个套接字生成一个pthread线程,这样生成的线程可以有自己的sigaction来处理具有指定回调的特定UDP端口 作为一个健全的检查,我昨天将UDP处理程序代码移动到了一个独立的构建中,以测试它,它可以正常工作。所有valgrind检查也未显示任何错误。当未

我不知道如何找出我的问题出在哪里

我试图将一个异步UDP处理程序合并到现有的FreeRTOS仿真器中,两者都是基于pthreads的。FreeRTOS实现本质上是pthreads的包装器,UDP处理程序生成一个FreeRTOS任务,然后为每个套接字生成一个pthread线程,这样生成的线程可以有自己的sigaction来处理具有指定回调的特定UDP端口

作为一个健全的检查,我昨天将UDP处理程序代码移动到了一个独立的构建中,以测试它,它可以正常工作。所有valgrind检查也未显示任何错误。当未添加、找到UDP处理程序时,FreeRTOS仿真器也是稳定的。可以找到不稳定积分

现在,当集成这两种行为时,我还不能成功地调试。这个bug表现为一个海森堡bug,因为在调试过程中,我不能总是重新创建它。所有valgrind(memcheck、helgrind和drd)都无法重新创建错误,只报告链接库(如SDL2、X11、mensa graphics等)中的错误。事后GDB能够捕获错误,并且在使用
(GDB)时,设置禁用随机化关闭

来自gdb的回溯显示了以下内容

(gdb)英国电信

#来自/usr/lib/libpthread.so.0的pthread_kill()中的0 0x00007faa2f45a41b

#1 0x0000564392f5c93b位于/home/alxhoff/git/GitHub/FreeRTOS Emulator/lib/FreeRTOS_Kernel/portable/GCC/Posix/port.c的prvResumeThread(xthread=0)中

#2 0x0000564392f5c38b位于/home/alxhoff/git/GitHub/FreeRTOS Emulator/lib/FreeRTOS_Kernel/portable/GCC/Posix/port.c:329的vPortYield()中

#3 0x0000564392f5d986,位于/home/alxhoff/git/GitHub/FreeRTOS Emulator/lib/FreeRTOS_Kernel/queue.c:1376

#在/home/alxhoff/git/GitHub/FreeRTOS Emulator/src/main.c:338中的vDemoTask1(pvParameters=0x0)中的4 0x0000564392f5b0d3

#5在/home/alxhoff/git/GitHub/FreeRTOS Emulator/lib/FreeRTOS_Kernel/portable/GCC/Posix/port.c:496的prvWaitForStart(pvParams=0x564392f5c754)中的0x00004392f5c754

#6 0x00007faa2f4524cf位于/usr/lib/libpthread.so.0的start_线程()中

#来自/usr/lib/libc.so.6的克隆()中的7 0x00007faa2efcd2d3

问题似乎是未向
prvResumeThread
传递有效的线程id,如#1所示。进入FreeRTOS源代码,我认为情况不应该如此,因为添加UDP处理程序及其各自的任务时会创建相同的线程,它们的添加不知何故导致FreeRTOS的
pxCurrentTCB
在执行
xTaskGetCurrentTaskHandle
时变得无效,该任务检索回溯的故障
prvResumeThread
调用的线程句柄。移动任务创建顺序会导致相同的错误,这使我认为我正在处理某种内存泄漏,但鉴于我无法使用valgrind重现错误,我不确定如何诊断错误

我担心这看起来像是一篇“调试我的程序”的帖子,但鉴于我在多线程调试方面的经验有限,我不确定我可以利用什么方法或工具来进一步诊断,我需要朝着正确的方向努力


干杯

也许这只是措词不当,但“派生线程可以有自己的sigaction,用指定的回调处理特定的UDP端口”,这表明可能存在误解。信号处理是整个过程的属性。单个线程没有自己的信号处理。不过,UDP服务器可能会为某些信号安装一个(一个)处理程序,并调用在每个线程基础上注册的回调函数。嗯,约翰·比林格补充说:我只熟悉POSIX的Linux实现,不确定要对哪些信号作出反应,以及以何种方式作出反应。但是请注意,在信号处理程序中,基本上调用任何系统调用(特别是与IO相关的调用)都是非常危险的。我真的不确定有什么保证,也不确定是否允许你依靠捕捉到的信号。只是要知道,信号是棘手的。对于你想通过信号做的大部分事情,还有其他选择。“任何选择都比使用信号要好。”约翰伯林格我想我说得很好。另外,这个异步处理程序是我为自己设置的学习信号的编程练习的结果,所以我还远远不够精通。对于打开的每个套接字,我在列表中创建一个pthread和一个条目,其中存储端口、文件描述符和回调之间的关系。每次触发sigaction时,都会搜索此列表并调用相应的回调函数,传递接收到的数据。我将fcntl与F_SETOWN和getId()一起使用,但在你说了这些之后,这似乎是错误的做法。我认为这有点夸张了@MichaelBeer。许多基本的POSIX I/O函数都是异步信号安全的,因此从信号处理程序调用并不是天生不安全的。此外,您可以或应该在信号处理程序中执行的操作通常取决于生成信号的原因,并且它是哪个信号可能会传递有关该操作的信息,但不同的信号编号并不必然对处理程序的操作提出不同的要求。然而,在这一点上,我们同意:信号是棘手的,通常还有其他替代方案,几乎任何可行的替代方案都适用于信号。我选择使用信号的能力是具有异步IO,这样FreeRTOS就可以安静地运行,直到出现UDP流量。我不太了解UDP线程如何影响FreeRTOS线程,特别是RTOS线程对我在UDP处理中使用的SIGIO没有任何依赖性。