views:

1221

answers:

4

I've obviously been spoiled by Visual Studio, because although I'm just learning Android and the Eclipse environment, debugging apps in Eclipse is becoming a serious detriment to further development.

For example, Eclipse will compile this divide by zero just fine:

public class Lesson2Main extends Activity
{
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate (savedInstanceState);

        int i = 1 / 0;

        TextView tv = new TextView (this);
        tv.setText ("Hello, Android!");
        setContentView (tv);
    }
}

And then, when it executes it under the debugger, I will get a full screen of useless debug info, non of which actually points me to the specific line containing the error.

The stackTrace is null within the exception ('e') info tree, and it simply states a message stating 'ArithmeticException'. (that's nice, how about you point me in the direction of where you found it!?)

I've looked all over the screen and am baffled that this IDE can't get this right. Does developing with Eclipse resort everyone back to 1991 with printf() like logging at every interval then to track down bugs? Seriously.

Is there a configuration or plug-in that I'm missing to help with this?

I haven't tested this case with XCode, but if the iPhone dev. IDE handles this more like Visual Studio, then no wonder the Android marketplace has so few apps.

I'm excited about Android, but it seems that Eclipse is getting in the way.

A: 

You are experiencing a typical problem of developing with a physical device as opposed to a piece of software on a machine.

It will point you to the specific error (Post the info and we can show you) Just look for your package names in the error it will show where the exception was thrown.

You should also use breakpoints to step through the process and see what happens the DDMS debugger should meet all your needed requirements.

And yes you should use logging Log.i(TAG, "Info: " + x);

You can't predict everything that happens and as your code base grows you will be glad you started doing this early.

steve
+11  A: 

Yes, you've missed one of the very important plug-ins for Eclipse called "LogCat". It catches all the debugging logs that your Android program gives, whether it's running on the Emulator or a real phone. The latter obviously requires that the phone be plugged in to the computer, and less-obviously, the setting in Application -> Development -> Enable USB Debugging be enabled.

The LogCat messages give you the full breakdown of what caused the error, including the line number. To open LogCat in Eclipse, go to Window -> Show View -> Other -> Android (one of the folders in the list) -> LogCat. Then dock the LogCat window somewhere where you can see it easily, and Eclipse will remember that location and open it up again next time your start it.

(Sometimes LogCat and the Emulator get disconnected from each other. The simple way to fix that is just to close Eclipse and the emulator, then restart them both.)

Steve H
As above you must be missing the log cat, having used VS I find programming and debugging in eclipse to be just as good
Donal Rafferty
Oh I know about LogCat and have it running too. It doesn't list the error either, and no pointer to any line #. I'm running with the Emulator v2.1. Check out my Eclipse LogCat here: http://www.appliedpda.com/Eclipse_LogCat.txt
Sebastian Dwornik
A system isn't useless simply because you can't operate it properly. If you look at Janusz's answer below, there's an example of what his LogCat gave when running your code, and as he points out very clearly, it shows the line number (14 for him) and the exact error type (divide by zero). I got a similar report. What happens is that when the debugger is attached, the exception logs don't get posted to LogCat until you terminate the application from within the Debug perspective. This happens because the application doesn't actually crash until the debugger detaches.
Steve H
[Quote: the exception logs don't get posted to LogCat until you terminate the application from within the Debug perspective] ------yup, that did it. Now I see the same exception. *AFTER* I let the program run through it's full crash and exit process. It should display that info when it halts my program and brings up the IDE debugger screens. Not leave me wondering and wasting my time with more clicking around. Eclipse has a long way to go it seems to compete with the likes of Visual Studio. Let's hope my patience for it outlasts my project. Thanks for the feedback. :)
Sebastian Dwornik
No problem. I agree, it's not all that intuitive, but once you've worked out how to use it it's not so bad. But hey, it's entirely free so we can't complain too much! :P
Steve H
Sebastian, don't rail on Eclipse. The issues you're seeing here are less Eclipse and more the Android devenv. If you were using Eclipse to debug normal Java code, you'd generally find that it's *at least* equal to VS. In many instances I actually prefer Eclipse.The Android devenv doesn't make the full debugging capabilities of Eclipse available to you.
Jon Bright
Thanks Jon, I can then only hope that the Android SDK team at Google see this and work to improve the Eclipse experience with such matters. Till then, more cranky developers are going to rail on these details. :)
Sebastian Dwornik
+5  A: 

I get the following stack trace in logcat:

03-31 17:01:11.272: ERROR/AndroidRuntime(205): java.lang.RuntimeException: Unable to start activity ComponentInfo{MyClass}: java.lang.ArithmeticException: divide by zero
03-31 17:01:11.272: ERROR/AndroidRuntime(205):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2401)
03-31 17:01:11.272: ERROR/AndroidRuntime(205):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2417)
03-31 17:01:11.272: ERROR/AndroidRuntime(205):     at android.app.ActivityThread.access$2100(ActivityThread.java:116)
03-31 17:01:11.272: ERROR/AndroidRuntime(205):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1794)
03-31 17:01:11.272: ERROR/AndroidRuntime(205):     at android.os.Handler.dispatchMessage(Handler.java:99)
03-31 17:01:11.272: ERROR/AndroidRuntime(205):     at android.os.Looper.loop(Looper.java:123)
03-31 17:01:11.272: ERROR/AndroidRuntime(205):     at android.app.ActivityThread.main(ActivityThread.java:4203)
03-31 17:01:11.272: ERROR/AndroidRuntime(205):     at java.lang.reflect.Method.invokeNative(Native Method)
03-31 17:01:11.272: ERROR/AndroidRuntime(205):     at java.lang.reflect.Method.invoke(Method.java:521)
03-31 17:01:11.272: ERROR/AndroidRuntime(205):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:791)
03-31 17:01:11.272: ERROR/AndroidRuntime(205):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:549)
03-31 17:01:11.272: ERROR/AndroidRuntime(205):     at dalvik.system.NativeStart.main(Native Method)
03-31 17:01:11.272: ERROR/AndroidRuntime(205): Caused by: java.lang.ArithmeticException: divide by zero
03-31 17:01:11.272: ERROR/AndroidRuntime(205):     at MyClass.onCreate(MyClass.java:40)
03-31 17:01:11.272: ERROR/AndroidRuntime(205):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1123)
03-31 17:01:11.272: ERROR/AndroidRuntime(205):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2364)
03-31 17:01:11.272: ERROR/AndroidRuntime(205):     ... 11 more

This is crystal clear. Look at the causing exception in line 14 of the stack trace and it says: Divide by zero. That is what you have done wrong. The next line says: at MyClass.onCreate(MyClass.java:40) This would be the line the exception occurs in. I don't get what would be difficult, or useless about this. How would VS present this?

Janusz
The thing which fooled me is that in the case of NULL deref a backtrace is presented by Eclipse 'before' you see any corresponding messages in logcat. Therefore you might have to persist through the backtraces/exceptions captured by Eclipse before seeing the pertinent logcat information.
tonylo
+6  A: 

(There's too much to say in a comment, so I'm writing this up as an answer.)

You can configure Eclipse to stop on exceptions that are caught, uncaught, or both. By default, Eclipse will break on any uncaught exception, and will ignore all caught exceptions (i.e. anything that is snagged by a try/catch block).

Things get a little weird for Android because you're running in an application framework, not a stand-alone application. As you can see from the stack trace posted above, the exception was actually caught by ActivityThread. This means that your initial exception is considered "caught", and won't trip Eclipse's break-on-uncaught handling until ActivityThread re-throws it. For this reason, the stack you see in the debugger when it stops is nowhere near your code.

Since you know you're getting an ArithmeticException, you can have it break on "caught" instances of that exception, and it will stop at the point of the throw. (Don't have it break on all caught exceptions -- you'll be hitting "resume" endlessly.)

As far as the logging being "late", if the debugger let the program continue to execute until the logging happened, you wouldn't be able to debug at the point of the throw.

fadden