为什么Android应用程序使用的本机共享库调试速度慢?

时间:2011-11-08 13:53:02

标签: android debugging shared-libraries gdbserver

我经常使用gdbServer来调试远程Android应用程序。我设置断点的区域是一个用c ++编写的共享库。

单步调试代码非常慢。有人知道为什么吗?我的假设是JNI对图书馆的调用造成了很大的延迟。

1 个答案:

答案 0 :(得分:1)

  

我的假设是JNI调用库会造成很大的延迟。

当您在断点处,并在GDB中执行step命令时,实际上没有发生JNI调用(您已经在本机代码中,只是继续直到下一行,或者进入下一个函数,什么是JNI与它有关吗?)

不幸的是,step即使在本地执行时也可能会很慢;特别适用于优化代码。

step命令如何工作?理论上,GDB可以检查当前行的指令,发现没有CALLJMP s,在下一行设置第一条指令的临时中断,然后继续。那会很快,但这不是GDB实际工作的方式。

它所做的更简单:它使处理器单步执行,并且每条指令都会问“我现在停在上一次停止的同一条线上了吗?”。如果“是”,则再次单步,直到答案为“否”。您可以通过设置set debug infrun 1

来观察此行为

根据当前行的指令数量,可能需要100个单步才能完成step命令。使用本机调试可能会很慢,使用远程gdbserver时可能会慢得多,因为每次单步完成时,GDB需要询问gdbserver“我现在在哪里”。这是GDB和gdbserver之间传播的大量数据包。您可以使用set debug remote 1观察这些数据包。

因此那些因素

  • GDB远程协议是“聊天”,
  • 每个数据包需要转到设备并通过(相对)慢速链接返回,
  • 单个step可能涉及其中的100个

结合起来产生你观察到的非常缓慢的step执行。

可能的解决方法是避免执行step。而是设置断点,并检查每个断点的程序状态。最终你会到达一个断点,它是bug的“下游”(即程序已经处于不良状态)。现在在那个“上游”的某个地方设置一个新的断点,并查看那里的状态。使用“分而治之”的方法,你很快就会解决这个问题。

相关问题