Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get the stacktrace in a mobile device?

I'm getting a NullPointerException in a Nokia S40.

I want to know what is causing this exception.

The device shows:

NullPointerException java/lang/NullPointerException

This error only occurs in the device, running in the emulator the application works fine.

I use microlog to debug my application. But the application works fine if the log is enabled.

Is there a way to get the stack trace when I get this NullPointerException? I don't need all details like the line number just which method cause this exception.

UPDATE: I installed the same application in another Nokia S40 and the same error didn't occur.

  • Nokia 2660 - error
  • Nokia 6131 - no error

UPDATE 2: Somehow I find what was causing the NullPointerException.

    import javax.microedition.lcdui.Canvas;
    import javax.microedition.lcdui.Graphics;

    public class OuterClass extends Canvas {

    private Config config;

    public OuterClass() {
        this.config = new Config();
    }

    public void paint(Graphics graphics) {
        HelperClass helper = new HelperClass(this.config);
        helper.doStuff();
    }

    public void dispose() {
        this.config = null;
    }

    public class Config implements IConfig {
        public int getSomething() {
            // ...
        }
    }
}


 public class HelperClass {

        private IConfig config;

        public HelperClass(IConfig) {
            this.config = config;
        }

        public doStuff() {
            config.getSomething(); // Here is thrown NullPointerException
        }
    }

In some situations a thread is started and call the OuterClass.dispose() before the helper.doStuff() causing the NPE. I think when I enabled the log it made the thread slower and helper.doStuff() was called when I expected it to be called.

like image 438
Daniel Moura Avatar asked Nov 26 '22 21:11

Daniel Moura


1 Answers

You are not going to find any way to save a Throwable stack trace on a Nokia Series40 handset.

The usual brute force way of debugging JavaME application on Series40 is to modify your code to create a stack trace yourself in memory.

What I'm talking about is:

  • Each Thread that you can identify (including system callback threads) needs its own Stack object, containing strings. Obviously, this increases the memory footprint of your application somewhat but keeping it in memory should limit the impact on race conditions.

  • When your code enters a method, it adds the method signature to the current Thread Stack. When the method exits (and you better only have one exit point per method) it pops the top of the Stack.

  • You can add aditional debug info on the stack, like values of variables in different places of the code.

  • You don't necessarily need to add this to every single method in your code.

  • You can add try{}catch(Throwable){} to the entry point of every thread you identified and either dump the stack in a file or on the screen (in a Form).

Obviously, this is not the kind of change you want to manually add in a lot of places in a large existing codebase. You can however make it part of your organisation coding standards for the future and write a source code parsing script to automatically add it to existing code.

like image 172
michael aubert Avatar answered Dec 05 '22 18:12

michael aubert