我想使用命令行在我的设备(Nexus One - 而不是模拟器)上调试我的 Android 应用程序。

我对如何使用 jdb 和 android.os.Debug.waitForDebugger 设置断点感到困惑。

假设我将以下代码放在我的主要 Activity onCreate 中:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    android.os.Debug.waitForDebugger();
    int j = 10;
    int r = j;
}

使用 ddms 我可以看到我的应用程序在我启动它时正在等待调试器(红色错误图标)。

但是,我不明白如何在 waitForDebugger() 调用之后设置断点,以便我可以开始单步执行。

显然,只附加 jdb 将立即继续运行应用程序而不会停止。

例如
jdb -attach localhost:8700

有没有办法在运行 jdb 之前预设断点或启动 jdb 设置断点然后附加的方法?

最佳答案

不幸的是,VM 无法告诉调试器它已经挂起。如果初始状态不是“正在运行”,我尝试过的各种调试器都会感到困惑。因此,在调试器连接后,VM 必须恢复所有线程。 (上述唯一的异常(exception)是如果 VM 刚刚启动,在这种情况下,它可以发送一个特殊的“我刚刚启动”消息,指示它是要运行还是保持挂起。这在这里没有帮助。)

waitForDebugger() 所做的是等到调试器的初始 Activity 爆发安静下来。调试器连接后,该方法将休眠,直到调试器在 1.5 秒内没有任何 Activity 。这允许调试器有机会在 VM 恢复之前设置任何断点。

对于 Eclipse,这个 hack 效果很好,因为您可以在附加之前配置断点。对于 jdb,我无法在它启动后告诉它附加,因此您必须快速敲击键盘或使用某种配置文件(我也没有看到)。

你可以用不同的方式解决这个问题:在 waitForDebugger 调用下面,添加一个循环,如:

static volatile boolean staticField = false;
  ...
while (!MyClass.staticField) {
    Log.d(tag, "waiting for go");
    Thread.sleep(2000);
}

然后,在你按照你想要的方式配置了 jdb 之后,使用类似的东西:
> set MyClass.staticField = true

如果你很快,你可以跳过循环,只使用 Thread.sleep(5000) 给自己一点额外的时间来猛击断点。

关于Android 与 jdb 混淆使用 waitForDebugger,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/3107587/

10-11 22:43