3

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

我对如何使用 jdb 和android.os.Debug.waitForDebugger.

假设我将以下代码放在我的主要活动中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设置断点然后附加?

4

3 回答 3

3

jdb 在 Linux 中有一个配置文件:~/.jdrbc。例如在我的我有:

stop in net.richardriley.myproj.myact.onCreate

在您的设备模拟器开发设置中,您可以为相关应用程序类设置“等待调试器”。运行应用程序,启动调试器,它将中断。

于 2010-08-12T19:42:34.910 回答
1

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

waitForDebugger() 所做的就是等到调试器的初始活动爆发安静下来。调试器连接后,该方法将休眠,直到调试器在 1.5 秒内没有任何活动。这使调试器有机会在 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) 给自己一点额外的时间来插入断点。

于 2010-06-24T19:43:37.800 回答
0

我已经尝试过两种解决方案(fadden 的一个和 Richard Riley 的一个),但都没有奏效。只要将 jdb 连接到调试端口(通过 Dalvik 的 8700),在模拟器中启动的应用程序就会畅通无阻,但随后它会自行运行,根本不与 jdb 同步。引入等待循环不会改变任何事情,.jdbrc 中的断点命令无效。jdb 的答案总是“延迟断点等。它将在加载类后设置。”,因为应用程序没有运行;但是,如果您键入“运行”,答案是“没有任何暂停。”,因为应用程序已经在运行......

于 2010-10-11T17:28:25.813 回答