C++线程不使用用户定义或python命令序列在gdb异步模式下停止

tim*_*ktu 6 python gdb asynchronous pthreads powerpc

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

编辑:我发现这个引用非常类似的问题主要gdb的邮件列表上.虽然我没有完全遵循Pedro关于异步模式限制的回应,但我认为他暗示在异步模式下,用户定义的命令序列的相对时序是不可信任的.这是我凭经验找到的.

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

(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 &
Run Code Online (Sandbox Code Playgroud)

此时,如果我手动发出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.
Run Code Online (Sandbox Code Playgroud)

然后由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.
Run Code Online (Sandbox Code Playgroud)

无论是否使用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 &")
Run Code Online (Sandbox Code Playgroud)

即使我from_tty=Truegdb.execute调用中指定,我也会得到相同的结果.此外,如果我使用continue -a它抑制错误字符串,但没有帮助,否则bc中断调用仍然无法正常工作.

所以...是这样的:

  • 驾驶舱错误?鉴于我正在努力实现的目标,是否存在我正在忽略或做错的事情?这应该工作,还是我必须使用GDB/MI异步"驱动"gdb这样?
  • 时间问题?在这种情况下,也许调用shell sleep(或python time.sleep())不会做我认为会做的事情.
  • 我使用pthreads的问题?我假设因为使用手动gdb命令总是正常工作,所以情况并非如此.
  • 一个gdb问题?

谢谢.

Tom*_*mey 1

我认为这很可能是 gdb 问题。我对劣质控制的了解还不够,所以无法更有信心。我确实知道较差的控制通常还没有连接到Python......

值得尝试的一件事是使用一个单独的 Python 线程来执行等待,然后使用 gdb.post_event 向主 gdb 线程发送“中断”命令。

然后,不要同步检查线程或在“中断”后执行工作,而是使用 gdb.events.stop 事件源来触发您的操作。

请慷慨地提交有关 Python API 中漏洞的错误。