I'd like to debug my Android application on my device (Nexus One - not the emulator) using the command line.
I'm confused at how to set a breakpoint using jdb in combination with android.os.Debug.waitForDebugger.
Say I put the following code in my main activity onCreate:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
android.os.Debug.waitForDebugger();
int j = 10;
int r = j;
}
Using ddms I can see that my application is waiting for the debugger (red bug icon) when I start it.
However, I don't understand how to set a breakpoint after the waitForDebugger() call so that I can start stepping.
Obviously just attaching jdb is going to immediately continue running the app without stopping.
e.g.
jdb -attach localhost:8700
Is there way to preset breakpoints prior to running jdb or a way to start jdb set breakpoints and then attach?
jdb has a config file : ~/.jdrbc in Linux. e.g in mine I have:
stop in net.richardriley.myproj.myact.onCreate
The in your device emulator dev settings you can set "wait for debugger" for the application class in question. Run the application, start the debugger and it will break.
Unfortunately, there is no way for the VM to tell the debugger that it's already suspended. The various debuggers I've tried get confused if the initial state is anything other than "running". As a result, after the debugger connects, the VM has to resume all threads. (The only exception to the above is if the VM was just started, in which case it can send a special "I just started" message indicating whether it's going to come up running or stay suspended. This doesn't help here.)
What waitForDebugger() does do is wait until the initial burst of activity from the debugger quiets down. After the debugger connects, the method will sleep until there has been no activity from the debugger for 1.5 seconds. This allows the debugger a chance to set any breakpoints before the VM resumes.
For Eclipse, this hack works out pretty well, because you can configure your breakpoints before you attach. For jdb, there's no way I can see to tell it to attach after it has started up, so you have to be quick on the keyboard or use some sort of config file (which I also don't see).
You could solve this a different way: below the waitForDebugger call, add a loop like:
static volatile boolean staticField = false;
...
while (!MyClass.staticField) {
Log.d(tag, "waiting for go");
Thread.sleep(2000);
}
Then, after you've got jdb configured the way you want, use something like:
> set MyClass.staticField = true
If you're quick, you could skip the loop and just Thread.sleep(5000) to give yourself a little extra time to slam breakpoints in.
I've tried with both solutions (the one from fadden and the one from Richard Riley), but none of them worked. The app launched in the emulator get unblocked as soon as a jdb is attached to the debug port (8700 via Dalvik) but then it runs on its own, without synchronizing with jdb at all. Introducing a waiting loop does not change things, and breakpoint commands in .jdbrc have no effect. Invariably, the jdb answer is "Deferring breakpoint etc. etc. It will be set after the class is loaded.", as the app was not running; but, if you type "run" the answer is "Nothing suspended.", as the app was already running...
Related
In my Android app developed in Kotlin I'm not able to make the debugger stop on breakpoints set at runtime in a Dynamic Feature with suspend functions. If I set the breakpoint before launching the app it works, but when I try to set the same breakpoint at runtime it doesn't, the debugger simply keeps skipping the breakpoints. I also checked "suspend all" in the breakpoint options to no avail, the debugger still skips the breakpoint. A very annoying situation because every time I need to pause the execution at a specif line in a suspend function, I must first stop the app, then set the breakpoint and then restart the app. Only in that case it works. On the contrary if I set a breakpoint in a no-suspend function, it works at runtime too. Any idea ?
I have some code that I run during onPause of an activity. I'd also like that code to run when I press stop in Android Studio, or press play and it automatically shuts down the activity before launching the new one. Is this possible?
No. The proper debugger is transparent to the code being controlled and the fact it's being stopped. stepped, paused or resumed should be 100% unnoticed by the code being tapped. Otherwise it would simply make rather little sense for 99,9% of cases.
You may however plant some code that will i.e. ensure that debugger is connected, like methods from Debug class, which often come handy as waitForDebugger() or isDebuggerConnected(). You can then ensure this code is stripped from release build with use of ProGuard.
The more similar thing to what you're asking is to detect if the debugger is attached, but as #Marcin-Orlowski says, aside from this debugger should be transparent.
This will return if debugger is attached:
android.os.Debug.isDebuggerConnected()
I am currently compiling and executing some C++ code on a rooted Android device. I use adb (adb shell). To compile my code, I don't use the NDK, but I cross-compile with CMake
I'm using the function sleep(seconds) of unistd.h.
I've experienced some curious behaviors with that function on Android: Basically, I have a for loop in which I std::cout something and then call sleep(x).
If I call sleep(1), the behavior is the one expected: The program waits 1 second, and then executes the next instructions.
If I call sleep(2), the behavior isn't the one expected. The program gets stuck on that instruction for ever.... until I hit a key on my PC keyboard (not the device's one), and then it gets stuck on the next sleep(2)... until I hit a key, etc...
This behavior happens only when the device screen is off. As soon as I click on the power button to turn the screen on, the program resumes and has the expected behavior.
N.B: The behavior is the same with usleep(useconds)
I have tried to see where the limit is between 1 and 2 seconds:
1.5s, 1.25s, 1.125s -> always stay blocked | 1.0625s -> ~50% chance of staying blocked.
Obviously, there is something that prevents a thread to wake up if it sleeps more than 1 seconds (at least 2).
So my question would be, does anyone have any idea of why this is happening, and has a detailed explanation of the process ?
Thank you !
Android puts applications in the background when they aren't doing any user interaction - unix sleep and java timers etc. won't wake them up. You have to use an android alarm or runnable postDelayed handler.
In Eclipse, I load up an Android Virtual Device, and then once it's loaded and not at the lock screen, I hit "Debug" on the Eclipse toolbar. My app runs fine (barring any errors from the last edit cycle, but that's what debugging is for). However, after I try to end my app (by hitting the back button from the main [only] activity - I have implemented a call to finish() as the last line of onBackPressed() , even though on further research it appears that hitting the back button from the main activity implicitly calls finish() ), it appears to not end the app.
The Eclipse debug perspective's Debug pane still shows the following:
MyAppName [Android application]
DalvikVM[localhost:8619]
Thread [<1> main] (Running)
Thread [<10> Binder_2] (Running)
Thread [<9> Binder_1] (Running)
I am assuming the DalvikVM line is the emulator. I do not knowingly spin up any extra threads in my app (light enough computations, so far, that I just do them all in the UI thread on button clicks, etc), so I have no idea whatsoever where Binder_1 and Binder_2 came from.
Also, when I go to debug again, thinking the app was fully shut down, the tool-tip on the debug icon is "Debug MyAppName (already running)".
Does finish() not terminate the application when it comes to Eclipse's debug hooks? Or, is there some other method I should call from the main activity that behaves like a "terminate()", that tells Android that not only the activity, but the whole app, is finished?
Yes, I am aware that Android apps' processes are not immediately killed when running on the device during the normal life cycle. I realize that I don't want to make my app kill its process stone cold dead when it comes to the shipped version. However, if this is the cause of the persistent debugger tie-in, I would at least like to implement something like if(DEBUG_MODE) trulyExit(); , either by teaching Eclipse to autokill after a finish() somehow, or by implementing some sort of trulyExit() in my main activity, to only be used during debugging. So, if I could get a few tips on how to teach Eclipse, or how one would implement a trulyExit(), that'd be awesome.
My workaround currently is closing the emulator each time. I can't think, though, that that's how you're supposed to end a debugging session...
Relevant dev environment info:
(OS: Windows 7 Professional)
IDE: Android Developer Tools build v22.0.1-685705
No additions/plugins to the ADT Eclipse, other than what Google's ADT download gives.
Test platform: Emulator, not device
(the USB port on my physical device is on the fritz, I am not sure if debugging tie-ins will still misbehave on it or not.)
This has been plaguing me for a few days now. Any time I try to use a breakpoint to debug into anything other than an activity (background service, broadcast receiver, input method) my breakpoint will be hit normally, but then about five seconds later the device will terminate the process and disconnect from the debugger. It isn't enough time to gather any meaningful information so debugging has proven extremely difficult.
Well it turns out I was finally able to figure it out after setting a bounty on this question...
For me it was because of threading, it seems threads were timing out when a breakpoint has been hit in a background thread. To solve this, I changed how the breakpoint suspends the app. Instead of just suspending the thread we're currently in I changed it to suspend all instead.
Right mouse click the break point and set it to suspend all, you can also set this as default as shown below.
I have just had the same problem
What happened for me was that I was in the middle of debugging when my phone (a ZTE blade) recieved a call. I took the call and when I came back to debugging again afterwards, I found that no matter what code I put on one particular line (probably the one where I had paused / had a break point when I recieved the call), the activity crashed (silently / without error message) when it hit that line.
After some messing around, I found if I added and removed a breakpoint on the offending line and added another in a different method later on, that the new breakpoint paused and after running the app through once, the whole thing was fine