我有一个包含2个线程的程序,其中一个重绘显示(使用ncurses),另一个在串口上运行inout处理,输出一些信息。
我发现在某些时候,第二个帖子因为我不知道的原因而挂起。如果:
,如何找到问题的根源select
和read
的顺序调用执行处理。是否有任何提示或技巧可以帮助我找到问题的根源并确定悬挂的原因?
更新。使用strace运行会在跟踪中将这些行打包给我:
waitpid(-1, 0xbfdcdfd0, 0) = ? ERESTARTSYS (To be restarted)
--- SIGCHLD (Child exited) @ 0 (0) ---
--- SIGCONT (Continued) @ 0 (0) ---
据我所知,这对应于我在程序中看到挂起的时间,用C-z
暂停它并查看跟踪文件(在整个程序完成之前没有写任何新内容)。每次重新启动线程都未更改后。
所以,这意味着有一个'流氓'waitpid
电话。我确信它在我的代码中的任何地方都没有以裸露的形式出现。遗憾的是,gdb没有在它上面设置断点 - 必须是某处的剥离符号问题。
答案 0 :(得分:1)
是否有任何提示或技巧可以帮助我找到问题的根源并确定悬挂的原因?
显而易见的答案是在挂起的线程上使用strace
来查看它正在做什么。
一个常见的错误是你希望读取一些字节数,并像这样循环:
while (bytes_remaining > 0) {
int n = read(..., bytes_remaining);
if (n == -1) {
// handle read error ...
break;
}
// save data we just got ...
bytes_remaining -= n;
// loop to read more data
}
此处的问题是read
可能会在0
上返回EOF
,并且您将永远循环播放。在strace
这将立即显而易见。
如果不是这样,你可以做的另一件事(假设Linux)是将GDB附加到挂起的线程而不是进程。