使用“jdb -attach”调试 Android 应用程序(或jswat)
我在模拟器上使用独立的 java 调试器和 Android 应用程序时遇到了麻烦。显然,任何具有远程功能的java调试器,例如jdb(或jswat)都可以通过遵循以下步骤来利用(据我在阅读此处和那里后的理解):
1)打开模拟器,在模拟器上安装您的应用程序(adb install)
2) 打开dalvik服务器(ddms)
3) 在模拟器上,运行“DevTools”应用程序 --> “开发设置”-->选择要调试的应用程序,启用“等待调试器”标志
4) 再次在模拟器中运行您的应用程序;它会阻塞,等待调试器连接,dalvik 将显示一个由“红色错误”标记的新进程
5) 在 dalvik 上,选择红色标记的进程;因此,其调试端口被转发到 localhost:8700
6) 将调试器挂接到 localhost:8700。使用 jdb,您必须运行“jdb -attach 8700”。
调试器一启动,您的应用程序在模拟器上就会解锁。因此,该应用程序似乎已正确检测到调试器,因此可以自由运行。
然而,要点是它“自由运行”,也就是说,它不会等待调试器发出“运行”命令。所以我没有机会设置任何断点。
按照 1 的提示,我尝试将等待循环放在我的应用程序的开头,希望我有时间设置断点。当我尝试设置断点时,jdb 说“推迟断点 XXX.YYY。它将在类加载后设置。”,因为应用程序尚未运行。但是,如果我随后发出“运行”命令,答案是“没有任何暂停。”,因为应用程序已经在运行(确实如此)。
使用jswat,您看不到所有这些消息,但最终结果是相同的:-(
不用说,“jdb -attach”对于在本地主机上运行的非android java应用程序来说效果很好。
任何提示(除了“请使用eclipse” “)?
我是不是在任何地方遗漏了一个愚蠢的细节?
该应用程序是 HelloWorld,构建命令是“ant debug”。
提前谢谢您。
I'm having troubles with using a stand-alone java debugger with android apps on emulator. Apparently, any remote-capable java debugger such as jdb (or jswat) could be leveraged, by following the steps below (as I understand after reading here and there):
1) turn on the emulator, install your app on the emulator (adb install)
2) turn on the dalvik server (ddms)
3) on the emulator, run the "DevTools" app --> "Development Settings" --> select the app you want to debug, enable the "Wait for debugger" flag
4) again in the emulator, run your app; it will block, waiting for a debugger to attach, and dalvik will show a new process flagged by a "red bug"
5) on dalvik, select the red-flagged process; its debug port is thus forwarded to localhost:8700
6) hook the debugger to localhost:8700. With jdb you have to run "jdb -attach 8700"
As soon as the debugger is launched, your app on the emulator unblocks. So, it seems that the app has properly detected a debugger and thus runs free.
The point, however, is that it "runs free", that is, it will not wait for the debugger to issue a "run" command. So I have no chance to set up any breakpoints.
Following hints from 1,I've tried putting waiting loops at the beginning of my app, in the hope I'd have the time to set a breakpoint. When I try to set a breakpoint, jdb says "Deferring breakpoint XXX.YYY. It will be set after the class is loaded.", as the app was not running yet. But, if I then issue a "run" command, the answer is "Nothing suspended.", as the app was already running (and it is indeed).
With jswat you don't see al these messages but the final result is the same :-(
Needless to say, "jdb -attach" works just fine with non-android java apps running on localhost.
Any hints (except "please use eclipse")?
Am I just missing a stupid detail anywhere?
The app is a HelloWorld, build command is "ant debug".
Thank you in advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
最好的方法似乎是在 .jdbrc 文件中设置断点,因为这些文件已加载并延迟,并且您不必更改代码来设置任意延迟循环以尝试在等待时捕获调试器。我和你一样,发现如果在类名上设置断点是行不通的。它说推迟到类加载完成,但是当类加载时 jdb 似乎永远不会收到通知。
特定类和行号处设置断点,它确实有效
但是,如果您在 .jdbrc 文件中的
:正如您所知,第一行不执行任何操作。第二行在这里对我有用:
所以关键似乎是在断点中使用特定的行号。尝试一下。希望它对您有所帮助并且也对您有用。
The best way seems to be to set the breakpoint in your .jdbrc file, since these are loaded and deferred and you don't have to change your code to set arbitrary delay loops trying to catch the debugger while it's waiting. I, like you, have found that it does not work if you set break points on a class name. It says deferring until the class is loaded, but then it seems the jdb never gets notified when the class is loaded.
However it does work if you set a breakpoint at a specific class and line number
in your .jdbrc file:
The first line does nothing, as you already know. The second line works for me here:
So the key seems to be to use specific line numbers in your breakpoints. Give that a try. Hope it helps you out and works for you too.
是的,它有效:-) 非常感谢你,codeboy2k!
我还做了更多的实验,如果指定方法名称(例如“stop in com.android.helloandroid.HelloAndroid.onCreate”),似乎它也可以工作。
因此,关键技巧是在 jdb 的启动文件中放置一个初始断点,这样应用程序将在该断点处阻塞,然后继续实际的调试会话。
我也尝试过使用 jswat,正确的过程如下:加载源代码,设置断点(至少是第一个断点),然后将调试器附加到应用程序(同时正在等待调试器)。从那时起,应用程序将从一个断点继续到另一个断点。然而遗憾的是,jswat 并没有在源代码本身上显示这个进度:-(
Yes, it works :-) Thank you very much, codeboy2k!
I've also made more experiments, and it seems that it also works if you specify a method name (e.g. "stop in com.android.helloandroid.HelloAndroid.onCreate").
The key trick, thus, is to put an initial breakpoint in the startup file of jdb, so the app shall block at that breakpoint, and then continue with the actual debug session.
I've also tried with jswat, and the correct procedure is as follows: load the source code, set up your breakpoints (at least the initial one), then attach the debugger to the app (that was meanwhile waiting for the debugger). From then on, the app will proceed from one breakpoint to the other. It is a pity, however, that jswat does not show this progress on the source code itself :-(
当您启动 dalvik 时,还要在命令行上查找 suspend=y JDWP 选项... 注意:我还没有对此进行测试,尽管 dalvik 能够使用正确的命令行选项挂起加载。
Also look for the suspend=y JDWP option on the command line when you launch dalvik... Note: I have not tested this, although dalvik has the capability to suspend on loading with the correct command line options.
我在非 Eclipse 设置中注意到的一件事是,如果 ADV 仍在运行,我可以附加调试会话(端口 8700),但我无法命中断点...关闭 ADV,它就可以工作。我不知道为什么,但这对我有用。
这里是我的设置,以防有帮助。我现在使用的是版本 17,但除此之外它的设置相同。
One thing I noticed on my non-eclipse setup is that if I have the ADV still running I can get the debug session to attach (port 8700) but I cant get the breakpoints to be hit ... close the ADV and it works. I have no idea why but this works for me.
Here is my setup in case it helps. I'm now on version 17 but other than that its the same setup.