6

我在嵌入式 powerpc 目标上使用 gdb 7.4.1 对使用 pthreads 的多线程 C++ 程序执行一些分析。我的最终目标是使用 python 编写 gdb 脚本以自动化一些常见的分析功能。问题是,当我单独运行命令与在 gdb 用户定义的命令(或通过 python 脚本调用相同的命令)中运行命令时,我发现行为存在一些差异。

编辑:我在主 gdb 邮件列表上发现了这个对一个非常相似的问题的引用。虽然我不完全遵循 Pedro 关于异步模式限制的回应,但我认为他的意思是在异步模式下,用户定义的命令序列的相对时间是不可信的。这是我凭经验发现的。

在这两种情况下,我执行以下启动步骤,加载我的程序,设置它的参数,并打开异步和不间断调试模式,然后在后台运行程序:

(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 &")

即使我from_tty=Truegdb.execute调用中指定,我也会得到相同的结果。此外,如果我使用continue -a它会抑制错误字符串但无济于事,否则中断调用仍然不起作用。

所以……这是:

  • 驾驶舱错误?考虑到我要完成的工作,我是否有遗漏或做错了什么?这应该可行,还是我必须像这样使用 GDB/MI 来异步“驱动”gdb?
  • 时间问题?在这种情况下,也许调用shell sleep(or python time.sleep()) 不会像我认为的那样做。
  • 我对 pthread 的使用有问题吗?我假设由于使用手动 gdb 命令始终可以正常工作,因此情况并非如此。
  • 一个gdb问题?

谢谢。

4

1 回答 1

1

I think this is most likely a gdb problem. I don't know enough about the inferior-control stuff to be more confident. I do know that inferior control generally has not been wired up to Python...

One thing worth trying is having a separate Python thread that does the wait, then sends an "interrupt" command to the main gdb thread using gdb.post_event.

Then, instead of synchronously examining the threads or doing work after the "interrupt", instead use the gdb.events.stop event source to trigger your actions.

Please file bugs liberally about holes in the Python API.

于 2013-05-24T18:34:04.437 回答