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

发布于 2024-08-02 00:47:26 字数 1606 浏览 4 评论 0原文

我在诺基亚 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() 。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

2024-08-09 00:47:26

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

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

我所说的是:

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

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

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

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

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

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

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.

风情万种。 2024-08-09 00:47:26

过去,我在尝试将堆栈跟踪打印到标准输出以外的其他位置时遇到了一些麻烦。 标准 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 字段被声明为最终字段。 如果您无法获取堆栈跟踪,并且在模拟器上运行应用程序时无法获取错误,请尝试在代码上创建跟踪项目符号(警报、日志,无论您能做什么)以隔离代码段问题正在发生。 它必须是可以在模拟器和真实设备之间发生变化的东西 - 例如,与在 RecordStore 中检索/保存记录、打开连接等相关的东西......当您遇到问题时,您尝试做什么?

I had some trouble in the past trying to print the stack trace to somewhere else than the standard output. The standard exception class doesn't provide the printStackTrace method that receives the output stream, therefore it only prints to the standard output stream.

It's possible, at least in Java SE, to redirect the java output stream to somewhere else by simply saying that System.out = . The PrintStream class receives an OutputStream, which means that you could create your own ByteArrayOutputStream, initialize a PrintStream, sets System.out to that stream, and then call ex.printStackTrace(). I don't have a J2ME environment here but I believe that, as long as it won't break when you try to set System.out to something else (nothing says that it's readonly in the docs), you should be able to do it.

After you do that, I would recommend writing it to a RecordStore that you have specifically for that, and then upload the records of that RecordStore to your server so you can get it.

I know it's not very easy but it may work. I would first test the System.out thing. If it works, everything else should work too.

My answer was wrong. As pointed out, the System.out and System.err fields are declared final. If you can't get the stack trace, and if you can't get the error when running the application on your emulator, try creating trace bullets on your code (alerts, logs, whatever you can) to isolate the piece of code where the problem is happening. It has to be something that could change between the emulator and the real device - for example, something related to retrieving/ saving records in a RecordStore, opening a Connection, etc... What did you try to do when you had the problem?

つ低調成傷 2024-08-09 00:47:26

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

微日志

You could use Microlog to send an e-mail when the exception occurs.

Microlog

缱倦旧时光 2024-08-09 00:47:26

您可以尝试在某些高级 try/catch 块中捕获异常,然后将跟踪通过电子邮件发送给自己。

You could try catching the exception in some high-level try/catch block and then emailing the trace to yourself.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文