views:

70

answers:

2

Hello,

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.

A: 

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:

stop in com.android.helloandroid.HelloAndroid
stop at com.android.helloandroid.HelloAndroid:21

The first line does nothing, as you already know. The second line works for me here:

Initializing jdb ...
*** Reading commands from /home/codeboy2k/.jdbrc
Deferring breakpoint com.android.helloandroid.HelloAndroid.
It will be set after the class is loaded.
> Deferring breakpoint com.android.helloandroid.HelloAndroid:21.
It will be set after the class is loaded.
> > Set deferred breakpoint com.android.helloandroid.HelloAndroid:21

Breakpoint hit: "thread= main", com.android.helloandroid.HelloAndroid.onCreate(), line=21 bci=11

 main[1] 

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
A: 

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 :-(

Giuseppe Ciaccio