Jump to content
Excelsior Forums
Sign in to follow this  
deiruch

NullPointerException in String.format

Recommended Posts

Hi there

I'm a developer of Cultris, a free tetris clone (http://gewaltig.net). The game is compiled & distributed with Excelsior JET & JetPack. It works quite well. We collect crash logs, recently I recieved one from an anonymous user with this excepction:

java.lang.NullPointerException
at java.util.Formatter.format(Formatter.class:0)
at java.util.Formatter.format(Formatter.class:0)
at java.lang.String.format(String.java:2838)
at net.gewaltig.cultris.game.achievements.DurationAchievement.achieved(DurationAchievement.java:69)
at net.gewaltig.cultris.game.challenges.Challenge.verifyAchievements(Challenge.java:69)
at net.gewaltig.cultris.gui.menu.GameChallenge.updateDT(GameChallenge.java:190)
at net.gewaltig.cultris.gui.OpenGLGUI.updateDT(OpenGLGUI.java:190)
at net.gewaltig.cultris.tools.UpdateManager.update(UpdateManager.java:63)
at net.gewaltig.cultris.Cultris.main(Cultris.class:98)

(The line numbers aren't correct). The interesting code is in DurationAchievement.achieved():

  public boolean achieved(Playfield _pf)
 {
   float rt=duration-(float)_pf.playDuration;
   if(rt<0)
     rt=0;

   if(bigLabel!=null)
     bigLabel.setCaption(String.format("%d:%05.2f",(int)rt/60,rt%60));

   return _pf.state==PlayfieldState.PLAYING && _pf.playDuration>duration;
 }

How on earth can this code throw a NullPointerException in String.format(...)?

The code was compiled with Excelsior Jet 7.2, J6SE 22. From what I see in the logs the user ran the game under Windows 7 x86 with lots of free memory on a quad-core machine.

Cheers,

Simon

Share this post


Link to post
Share on other sites

Yes, of course. But without any success.

You may try to write a stress test executing this code fragment in multiple threads on a quad-core box.

Please let us know if you manage to reproduce the problem.

Share this post


Link to post
Share on other sites

More random crashes...

java.lang.StringIndexOutOfBoundsException: String index out of range: 3
at com.excelsior.internal.lang.KeyStrings.newString(KeyStrings.java:95)
at java.lang.StringBuffer.toString(StringBuffer.java:592)
at net.gewaltig.cultris.gui.controls.CLabel.reflow(CLabel.java:190)
at ...

I cannot reproduce any of the issues on my machine reliably. And idea what to do next?

Share this post


Link to post
Share on other sites

More random crashes...

java.lang.StringIndexOutOfBoundsException: String index out of range: 3
at com.excelsior.internal.lang.KeyStrings.newString(KeyStrings.java:95)
at java.lang.StringBuffer.toString(StringBuffer.java:592)
at net.gewaltig.cultris.gui.controls.CLabel.reflow(CLabel.java:190)
at ...

I cannot reproduce any of the issues on my machine reliably. And idea what to do next?

This crash indicates that internal structure of StringBuffer was corrupted from outside. Really, StringBuffer.toString() cannot produce StringIndexOutOfBoundsException. So I suspect that it is a sort of hardware problem. Does this crash (and above) occur on PC of one user or you have a bunch of the same crash logs from different users?

Share this post


Link to post
Share on other sites

This crash indicates that internal structure of StringBuffer was corrupted from outside. Really, StringBuffer.toString() cannot produce StringIndexOutOfBoundsException. So I suspect that it is a sort of hardware problem. Does this crash (and above) occur on PC of one user or you have a bunch of the same crash logs from different users?

I have similar crashlogs from all over the world (different operating systems & hardware). That's why I suspect it's not a hardware issue. Since we use some native libraries it might well be that one of them corrups memory somehow. But I have no idea how I could verify this hypothesis.

Share this post


Link to post
Share on other sites

I have similar crashlogs from all over the world (different operating systems & hardware). That's why I suspect it's not a hardware issue. Since we use some native libraries it might well be that one of them corrups memory somehow. But I have no idea how I could verify this hypothesis.

Yes, most likely it's a misbehaving native library. I would try to disable them one-by-one, or use older/newer versions.

Share this post


Link to post
Share on other sites

Yes, most likely it's a misbehaving native library. I would try to disable them one-by-one, or use older/newer versions.

But our game depends on those libraries. It doesn't work without them. And I don't have a way to reproduce the problem on my machine. So how do you suggest to solve the problem?

Fact is, that the Oracle JVM doesn't crash.

Share this post


Link to post
Share on other sites

But our game depends on those libraries. It doesn't work without them. And I don't have a way to reproduce the problem on my machine. So how do you suggest to solve the problem?

What exactly are those libraries? Cannot you subset your game's source so that it does not use one of them? Or perhaps you can switch off a feature (e.g. audio)?

Fact is, that the Oracle JVM doesn't crash.

We had a few customer issues like this in the past, and most of them were JNI misuses that did not trigger any crashes on the Sun JRE simply by coincidence. And all those apps crashed when run on JRockit and/or IBM JDK.

Our CTO had written an article closely related to this topic last year:

Switching JVMs May Help Reveal Issues in Multi-Threaded Apps

I am not ruling out a bug in our product, but we need some way to reproduce it reliably.

Share this post


Link to post
Share on other sites

We had a few customer issues like this in the past, and most of them were JNI misuses that did not trigger any crashes on the Sun JRE simply by coincidence. And all those apps crashed when run on JRockit and/or IBM JDK.

Our CTO had written an article closely related to this topic last year:

Switching JVMs May Help Reveal Issues in Multi-Threaded Apps

Thanks for the article. I believe I read some similar stories on the Excelsior Blog or somewhere in the support section. I understand that many people think your product is buggy when in fact they write code with race-conditions... Thank you for still being so nice after all this time :)

I am not ruling out a bug in our product, but we need some way to reproduce it reliably.

That's exactly the problem: Reproducing the bug reliably.

So far I couldn't find a way to do that. The game works with Oracles JVM on Windows XP to 7, all 32 bit. It works on OS X 10.6. The only weird bug reports come from the Excelsior JET builds. I tested with JRockit too, but wasn't able to get it to crash (but I'm also unable to crash it with Excelsior - so that has nothing to say). It might *very well* be that there's a bug in the libraries we use or in our code - the problem is that I have no idea where to look for a bug.

Aren't there additional logs we could enable? Or compiler flags so that the game would crash immediately when something goes south instead at some random location?

What exactly are those libraries? Cannot you subset your game's source so that it does not use one of them? Or perhaps you can switch off a feature (e.g. audio)?

The libraries we use are:

Do you suggest we deploy the game without music and sound effects? The bugs are rare - letting thousands people download a version without music/sound would be worse IMHO.

Share this post


Link to post
Share on other sites

Do you suggest we deploy the game without music and sound effects? The bugs are rare - letting thousands people download a version without music/sound would be worse IMHO.

Cannot you send a version without sound specifically to people who reported the problem?

Also try running my app on the conventional JRE with the -Xcheck:jni option and see if that generates any warnings on your system and on those people's systems.

Share this post


Link to post
Share on other sites

Cannot you send a version without sound specifically to people who reported the problem?

Sadly not. We collect anonymized crash reports and 99% of the users don't enter contact information. Also there is no fixed set of machine where it crashes - it crashes sometimes on machines where we know that it ran fine for the last few months. Then, a crash out of nowhere, and after that no more crashes from that machine.

Also try running my app on the conventional JRE with the -Xcheck:jni option and see if that generates any warnings on your system and on those people's systems.

"My app?" I couldn't find an attached app. If you meant "your app": I tested with both, the -Xcheck:jni and the (Oracle-recommended) -XX:+CheckJNICalls options to no avail. It didn't report errors.

The beta release notes of the next contain bits about stability-related changes. We'll see if future versions behave differently.

Share this post


Link to post
Share on other sites
The beta release notes of the next contain bits about stability-related changes. We'll see if future versions behave differently.

Ok, I have some new data from the field. The newest release, compiled with 7.6MP2 still shows the same symptoms:

Random "impossible" exceptions from all over the place. But doesn't happen often or regularly and on a variety of machines (different Windows versions, different CPUs, ...).

The latest crash was a NullPointerException in a method that only accesses initialized constants and an initialized local array.

Share this post


Link to post
Share on other sites

I now also ran our game with AppVerifier and with debug DLLs with all checks enabled. The only thing I could find were some memory leaks in the Intel OpenGL drivers...

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×