【问题标题】:Detect blocking call in multithreaded C++ application检测多线程 C++ 应用程序中的阻塞调用
【发布时间】:2020-04-18 20:19:50
【问题描述】:

在 C++ 应用程序中,我有来自同一类的 2 个线程(thread1thread2)。他们正在非常快速地运行一个循环,并且不会在循环内进行任何阻塞调用:

while (!end) {
  //dostuff, no blocking!
}
cout << "ended" << endl;

应用程序中存在一些错误,因为当我一次只运行一个线程时,我设置了它的end 属性,它可以成功退出循环。

但是,如果我同时运行两个线程,有时其中一个线程无法从循环中跳出(尽管设置了 end 属性)。

循环本身相当大(几百行),我可以在其中放置一个(条件)断点,但是当我单步执行时,我失去了功能(因为线程应该运行得很快),所以即使我找到了哪些行块,可能是走错路了。

所以,我的问题是:gdb 中是否有任何选项可以让断点的行为类似于看门狗? 即:如果在一定时间内它不会被击中,它应该会中断线程,所以我可以检查哪一行导致了问题。

【问题讨论】:

  • end 的声明是什么?是atomic吗?
  • 如果你的线程被阻塞了,那么简单的闯入可能会直接导致阻塞,不是吗?从这个模糊的问题描述来看,似乎存在某种竞争条件而不是阻塞调用。所以你可能应该检查变量是否正确同步,end 条件不是volatile 等等。
  • 正如 user7860670 所建议的,当您发现线程阻塞时,为什么不直接中断 gdb 呢?您可以执行多个中断/继续循环来检查它是否总是在同一位置阻塞。
  • 结束是原子的,是的,而不是volatile
  • 不需要附加 gdb,因为我从一开始就通过 gdb 运行它。

标签: c++ multithreading debugging gdb


【解决方案1】:

即:如果在一定时间内它不会被击中,它应该会中断线程,所以我可以检查哪一行导致了问题。

您不需要此功能来检查哪条线路导致问题(并且该功能不存在)。

等待“不退出”条件发生,然后按 Control-C。 GDB 将停止该进程的所有线程,并为您提供(gdb) 提示。此时,发出thread apply all where 命令,您将看到“未退出”线程卡在哪里。

【讨论】:

  • 是的,但问题是 gdb 无法挂起这个阻塞线程。当我尝试它超时时,线程突然消失了。这有效吗?
  • 您可以尝试使用 kill -INT &lt;pid&gt; 从终端手动中断正在调试的进程。您可能还想阅读this post
猜你喜欢
  • 2010-10-07
  • 2012-10-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-30
  • 2022-08-12
  • 2012-06-26
  • 1970-01-01
相关资源
最近更新 更多