如何在移动设备中获取堆栈跟踪?

时间:2009-08-13 19:54:33

标签: java debugging java-me stack-trace

我在诺基亚S40中遇到NullPointerException。

我想知道导致此异常的原因。

设备显示:

  

NullPointerException java / lang / NullPointerException

此错误仅发生在设备中,在模拟器中运行,应用程序正常工作。

我使用microlog来调试我的应用程序。但是如果启用了日志,应用程序就可以正常运行。

当我得到这个NullPointerException时,有没有办法获得堆栈跟踪?我不需要像行号这样的所有细节,只是哪种方法会导致此异常。

更新:我在另一台诺基亚S40中安装了相同的应用程序,但没有发生同样的错误。

  • 诺基亚2660 - 错误
  • 诺基亚6131 - 没有错误

更新2:不知何故,我找到导致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
        }
    }

在某些情况下,启动线程并在helper.doStuff()之前调用OuterClass.dispose(),从而导致NPE。我想当我启用日志时,它使线程变慢,并且当我预期它被调用时调用了helper.doStuff()。

4 个答案:

答案 0 :(得分:2)

您无法找到任何方法来保存诺基亚Series40手机上的Throwable堆栈跟踪。

在Series40上调试JavaME应用程序的常用蛮力方法是修改代码以在内存中自己创建堆栈跟踪。

我所说的是:

  • 您可以识别的每个线程(包括系统回调线程)都需要自己的Stack对象,包含字符串。显然,这会增加应用程序的内存占用,但保留在内存中会限制对竞争条件的影响。

  • 当您的代码输入方法时,它会将方法签名添加到当前的线程堆栈中。当方法退出时(每个方法最好只有一个出口点),它会弹出堆栈的顶部。

  • 您可以在堆栈上添加aditional调试信息,例如代码不同位置的变量值。

  • 您不一定需要将其添加到代码中的每个方法中。

  • 您可以将try{}catch(Throwable){}添加到您标识的每个线程的入口点,并将堆栈转储到文件或屏幕上(在表单中)。

显然,这不是您希望在大型现有代码库中的许多位置手动添加的更改。但是,您可以将其作为组织编码标准的一部分,并编写源代码解析脚本以自动将其添加到现有代码中。

答案 1 :(得分:0)

我在过去尝试将堆栈跟踪打印到标准输出以外的其他地方时遇到了一些麻烦。标准exception类不提供接收输出流的printStackTrace方法,因此它只打印到标准输出流。

至少在Java SE中,可以通过简单地说System.out =将java输出流重定向到其他地方。 PrintStream类接收一个OutputStream,这意味着您可以创建自己的ByteArrayOutputStream,初始化PrintStream,将System.out设置为该流,然后调用ex.printStackTrace()。我没有这里的J2ME环境,但我相信,只要当你尝试将System.out设置为其他内容时它不会中断(没有人说它只是在文档中只读),你应该能够做到它

执行此操作后,我建议将其写入专门用于此的RecordStore,然后将该RecordStore的记录上传到您的服务器,以便获取它。

我知道这不是很容易,但可能有用。我首先测试System.out的事情。如果它有效,其他一切也应该有效。

我的回答是错误的。正如所指出的,System.out和System.err字段被声明为final。如果您无法获得堆栈跟踪,并且在模拟器上运行应用程序时无法获得错误,请尝试在代码上创建跟踪项目符号(警报,日志,无论您可以做什么)以隔离代码段问题正在发生。它必须是模拟器和真实设备之间可能发生变化的东西 - 例如,与在RecordStore中检索/保存记录,打开连接等相关的东西......当你遇到问题时,你尝试做什么?

答案 2 :(得分:0)

发生异常时,您可以使用Microlog发送电子邮件。

Microlog

答案 3 :(得分:-2)

您可以尝试在某个高级try / catch块中捕获异常,然后emailing追踪自己。