37

I can't see anything functionally wrong in terms of what gets executed, but I've just wasted an hour proving my code and the compiler are doing what they're supposed to.

Consider this code:

public int getAnswer(int a) {

    int retval = 18;

    int x = 25;
    int y = 50;

    while (a-- > 0) {
        if (a == 3) {
            retval = a;
            return retval;
        }
    }

    x = 10;
    y = 20;

    return 0;
}

Called with

int theAnswer = getAnswer(6);

Breakpoint both of the lines containing return and before you run the code, try and predict the result, and therefore which line will be hit.

As you might imagine from the tone of my question, the wrong line is highlighted, but the right result is returned. If you step through the code, it dances around quite a bit.

Is there anything that can be configured differently such that the correct lines are displayed? (I'm using the latest Android Studio, which I appreciate is potentially unstable, but I'm sure I've seen similar behaviour on Eclipse a while back but I never spent the time then tracking it down; perhaps it's a java thing).

3 Answers3

44

This is a problem with dx, which is the part of the build that turns your Java .class files into .dx files for packaging into Android. According to this:

https://code.google.com/p/android/issues/detail?id=34193

if a function has multiple return paths, dx merges the return instruction into a single return instruction, so during debugging, the debugger can't tell which line a return belongs to and things jump around. This corresponds to what I see when I try to reproduce your problem: each time through the loop it does the if (a == 3) check, jumps to the return 0 at the end, and then jumps back into the loop. You're seeing that last return 0 get merged with the return retval in the middle of the loop.

I doubt this will be fixed any time soon, so you may just have to learn to live with it. Sorry, I know it's kinda crazy.

Scott Barta
  • 79,344
  • 24
  • 180
  • 163
  • 1
    Thanks. Shame this dx "optimization" can't be disbled in debug mode. –  Feb 19 '14 at 11:54
  • It's not an optimization. It's the binary format for the Dalvik VM; you can't run .class files directly on Android. – Scott Barta Feb 19 '14 at 16:32
  • 2
    Not dx itself; I mean couldn't it create multiple return instructions, as in the source code? –  Feb 19 '14 at 20:40
  • 1
    This answer is great. – Nathaniel D. Waggoner Sep 17 '14 at 20:35
  • 2
    I have suffered through this as well... I understand there is a "reason" for it, but it is simply unacceptable. It is a serious design problem in dx that needs to be addressed. iOS and other mobile platforms do not have such an issue that makes life very difficult for developers – JoelFan Jan 11 '15 at 15:30
  • this didn't work for me. what did work was the accepted answer in this similar SO post: http://stackoverflow.com/questions/21743442/cant-reach-some-lines-debugging-android-app – Joris Weimar Mar 30 '16 at 10:05
  • I'm with JoelFan here, it's not acceptable that a language and its debugger do not allow you to execute your code step by step a the symbolic level it is written. – Guy Moreillon Aug 08 '16 at 07:13
2

Try Build -> Rebuild project and then Shift + F9. You have outdated code running on application.

Roger Alien
  • 3,040
  • 1
  • 36
  • 46
  • No, it's not that. Cleaned, rebuilt, remade, moved code around a little just for the sake of it too - no difference. I created a new test project just to check it, and I'm running it on an actual device, not an emulator. Try it! –  Feb 16 '14 at 01:17
  • I'm using intellij IDEA(which is the same) for several years for android development, and the issue you described appeared to me only when i faced outdated code. Maybe you are debugging library code? If not, then sorry i don't know what's wrong you may do. – Roger Alien Feb 17 '14 at 01:29
  • No, I literally just create a new test Android project using Android studio, cut and paste the code about into it and call it from onCreate and it behaves exactly the same way every time. –  Feb 17 '14 at 09:17
2

Here's what worked for me, at least for stepping into Android SDK source code:

  1. Install the SDK Platform and Sources for Android SDK for exactly the API level of the version of Android you are running during development (use the Android version history page to find out which API level your device has).
  2. Compile your app for exactly that version. For example, in Android Studio, open your app's build.gradle file and set the value of compileSdkVersion accordingly.
  3. Debug your app. When you step into Android SDK source, you should see the correct line.
  4. (optional) Recompile with the latest SDK before deploying. In other words, change compileSdkVersion back.
Gary Sheppard
  • 4,764
  • 3
  • 25
  • 35
  • This works for none SDK code too. I switched my min API version to match my target device and now the debugger is showing the correct lines. – Graeme Sep 11 '16 at 01:49