使用多线程调试C程序

3
我想调试一个运行多个TCP服务器线程的C程序。由于我必须在嵌入式Linux(busy box)中进行调试,因此无法设置复杂的调试工具。我希望它能本地支持gdb。
所以我开始使用gdb。一旦我输入run,服务器似乎在后台运行,但gdb返回提示和“Program received signal SIG64 (Real-time event 64)”消息(与pthread有关)。我知道这与主线程被分叉成几个线程有关。但我不知道如何调试这个问题。任何起点都会很有帮助。
另外,是否有其他“trace”之类的调试器,占用空间小,可以使用?
请帮忙。
5个回答

9

通常情况下,使用调试器调试多线程应用程序是困难的。最好的方法是尝试将错误隔离到单线程情况下,或在可疑位置使用调试打印,直到发现错误。

虽然这对于您的具体问题没有帮助,但这是我在处理多线程应用程序时学到的最好建议,特别是嵌入式系统。


2
考虑到程序的多线程特性,因此在使用调试打印时,请勿依赖于不同线程之间打印顺序。 - Alok Save
5
在这种情况下,最好有一个“日志记录器”线程,在其中通过消息队列(例如 msgqueue)发送要打印的消息。日志记录器线程会为每条消息添加时间戳,并按接收到它们的顺序打印它们。 - Xavier T.
@Xavier:确实是个好建议,但对于时间敏感的问题帮助不大,但肯定值得一试。 - Alok Save
@Als:我同意,精确的时间可能会有所偏差,但是事件序列应该得到尊重,这可能足以解决一些问题。 - Xavier T.
Mr.32提供了一个讨论此记录器线程的帖子链接...看看吧。这似乎并不容易。我可以看到很多免责声明 :) https://dev59.com/pVvUa4cB1Zd3GeqPqBvd - user489152
显示剩余2条评论

3
在这种情况下,我通常会这样做:
1.创建一个线程日志文件,并将所有的标准输出和标准错误输出重定向到该日志文件中......也许这个链接对您有所帮助:在多线程应用程序中,如何根据线程将stderr和stdout指向不同的文件? 2.跟踪所有线程之间的全局变量。不正确地使用全局变量往往会导致问题。
3.如果您正在使用互斥锁,请检查它是否会创建死锁。在条件和信号量设计中,始终尝试在纸上跟踪所有这些线程。

1

我建议您使用像valgrind这样的内存访问检查程序。在我的情况下,许多错误都是由于非法内存处理引起的。在多线程程序中找到错误很困难,因此使用内存泄漏检查程序是找出错误原因的更好方法。


Valgrind 可能无法在带有 BusyBox 的嵌入式 Linux 上运行。 - Eli Iser
@Eli lser 我尝试在s3c6410嵌入式板上使用valgrind。编译成功,但实际上我未能加载valgrind,因为一些共享对象版本与valgrind不匹配。如果busybox包含适当的so文件,则可以解决此问题。 - JayMuzie
1
我使用了 -lmcheck 编译我的代码,并解决了几个“泄漏”的指针 :) - user489152

0

0

一些棘手的想法..

  1. 将 sleep(一些时间)添加到线程中以作为起点进行调试
  2. 程序运行后,检查线程的 pid(使用带有 -L 选项的 ps 命令)
  3. 在 gdb 提示符中运行 gdb 程序 {pid} 或调用 attach {pid}
  4. 在睡眠后,您可以跟踪该线程的下一步操作

不要忘记在睡眠时间结束之前完成附加。

如上所述,测试单个线程或使用文本日志记录设施是一个好选择。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接