我在嵌入式 powerpc 目标上使用 gdb 7.4.1 对使用 pthreads 的多线程 C++ 程序执行一些分析。我的最终目标是用 python 编写 gdb 脚本来自动化一些常见的分析功能。问题是,当我单独运行命令与在 gdb 用户定义的命令(或通过 python 脚本调用相同的命令)中运行命令时,我发现行为存在一些差异。
编辑:我找到了this引用主要 gdb 邮件列表上的一个非常相似的问题。尽管我不完全遵循 Pedro 关于异步模式限制的回应,但我认为他是在暗示在异步模式下,用户定义的命令序列的相对时序是不可信任的。这是我凭经验发现的。
在这两种情况下,我都执行以下启动步骤,加载我的程序,设置它的参数,打开异步和不间断 Debug模式,然后在后台运行程序:
(gdb) file myprogram
(gdb) set args --interface=eth0 --try-count=0
(gdb) set target-async on
(gdb) set pagination off
(gdb) set non-stop on
(gdb) run &
此时,如果我手动发出 interrupt
命令,然后发出 info threads
命令,我会看到除已停止的线程之外的所有正在运行的线程的列表。然后我可以 continue &
并重复我的心内容,它始终如一地工作。停止时,我可以检查该线程的堆栈帧,一切正常。
但是,如果我将这些命令放入用户定义的 gdb 命令中:
(gdb) define foo
(gdb) interrupt
(gdb) info threads
(gdb) continue &
(gdb) end
(gdb) foo
Cannot execute this command while the selected thread is running.
然后 foo 打印的线程列表表明没有线程被停止,因此 continue &
命令返回 Cannot execute this command while the selected thread is running.
。我认为这是异步 gdb 命令固有的问题,所以我在中断命令后插入了一个荒谬的漫长等待并得到了相同的行为:
(gdb) define foo
(gdb) interrupt
(gdb) shell sleep 5
(gdb) info threads
(gdb) continue &
(gdb) end
(gdb) foo
Cannot execute this command while the selected thread is running.
无论有没有 sleep 命令,我总是可以发出手动 CLI 命令并且线程被正确停止。
类似地,我通过获取 python 脚本来细读线程得到了相同的结果:
import gdb, time
gdb.execute("file myprogram")
gdb.execute("set args --interface=eth0 --try-count=0")
gdb.execute("set target-async on")
gdb.execute("set pagination off")
gdb.execute("set non-stop on")
gdb.execute("run &")
time.sleep(5)
gdb.execute("interrupt")
# here, I inspect threads via gdb module interface
# in practice, they're always all running bc the program neven got interrupted
for thread in gdb.selected_inferior().threads():
print thread.is_running(),
gdb.execute("continue &")
即使我在 gdb.execute
调用中指定 from_tty=True
,我也会得到相同的结果。此外,如果我使用 continue -a
它会抑制错误字符串但无济于事,因为中断调用仍然不起作用。
所以...是这样的:
- 驾驶舱错误?考虑到我想要完成的事情,是否有我遗漏或做错的事情?这应该有效,还是我必须使用 GDB/MI 像这样异步“驱动”gdb?
- 时间问题?在这种情况下,调用
shell sleep
(或python time.sleep()
)可能不会像我假设的那样。 - 我对 pthreads 的使用有问题吗?我假设因为使用手动 gdb 命令总是能正常工作,所以事实并非如此。
- gdb 问题?
谢谢。
最佳答案
我认为这很可能是 gdb 问题。我对低级控制的东西了解得不够多,无法更有信心。我知道劣质控件通常没有连接到 Python...
值得尝试的一件事是让一个单独的 Python 线程执行等待,然后使用 gdb.post_event 向主 gdb 线程发送“中断”命令。
然后,不是同步检查线程或在“中断”之后执行工作,而是使用 gdb.events.stop 事件源来触发您的操作。
请大量提交有关 Python API 中的漏洞的错误。
关于python - 使用用户定义或 python 命令序列的 C++ 线程不会在 gdb 异步模式下停止,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10607021/