IT大道IT大道

首页 >  技术 > The Folder of God

The Folder of God

原文 https://www.excelsiorjet.com/blog/support-stories/the-folder 2017-10-12 04:30:30 0 评论

Is it possible to make all Java applications crash by creating an empty folder? You know, “right-click, New, Folder, type folder name, Enter”? Yes, but that has to be a very special folder.

Recently, we had several users report a similar problem over a short time frame: theirnatively compiled Java applications crashed on Windows on every run.

All crash logs contained the same clues:

  1. O/S version: always Windows 10 Creators Update,
  2. Crash location: always somewhere inside msvcr100.dll , but offsets differed from launch to launch,
  3. The Java part of the stack trace always ended with:
    sun.awt.shell.Win32ShellFolder2.getDisplayNameOf(Native Method)
    sun.awt.shell.Win32ShellFolder2.<unknown>(Unknown Source)
    sun.awt.shell.Win32ShellFolder2$13.call(Unknown Source)
    sun.awt.shell.Win32ShellFolder2$13.call(Unknown Source)
    ...

What’s more, along with our JVM we provide tools that help our users configure the AOT compiler and package their natively compiled applications for distribution. These tools are themselves Java applications compiled with Excelsior JET. And some of our customers observed similar crashes when launching those tools as well.

However, we hadn’t managed to reproduce the problem in our lab. That was not overly surprising, because we, of course, had tested our product on Windows 10, including the Creators Update, and on our systems everything worked fine, without any crashes. If there was such a critical bug, we would have found it long before release.

All those clues pointed to the fact that the problem was not actually specific to Excelsior JET.

A brief search through the OpenJDK bug tracker and bingo: JDK-8173471, JDK-8179014, and other linked issues share the same symptoms: crash address in msvcr100.dll , stack trace as in the crash logs sent by our customers, and the same flavor of Windows. That just could not be a coincidence.

And then we found a threaddiscussing exactly this problem on a Microsoft support forum. Among the answers in that thread there was a strange one:

if you had created a GodModefolder, then deleting the folder would solve the problem

Wait a second… is that a joke?

The Windows Master Control Panel shortcut, dubbed “Windows God Mode” by bloggers, is indeed just a shortcut that lets you see all operating system control panels in one place. To create it, you just need to include a magic GUID in the name of a newly created folder. Being an undocumented feature, it doesn’t look 100% safe, of course, but still, how can it crash Java applications even if they work on totally different JVMs?

However hard it was to believe, we asked one of the customers who reported the problem to try the above “solution”. (It actually felt rather strange to ask a customer about such things as “God Mode folder”, but that was our best, if not the only, idea at that time.) And you know what? The customer confirmed that they indeed had a God Mode folder on their desktop and that it was never a problem before, but there were no more Java application crashes after deleting it! Things were getting stranger and stranger.

Reveal

So, what was actually going on there? To understand that, your can read the history of JDK-8179014, or its short summary below:

  • There is a system method IShellFolder::GetDisplayNameOf(...) in Shell32.dll that retrieves the display name of a given folder or file.
  • For whatever reason, in Windows 10 Creators Update that method returns S_OK for the God Mode folder, but in the output STRRET structure, the field that is supposed to point to the buffer containing the resulting string is NULL .
  • As it was not the case in any previous version of Windows and does not happen for any other folder or file, the native method sun.awt.shell.Win32ShellFolder2.getDisplayNameOf(...) called that system method, but did not handle the above situation. That caused a crash when the method was called for the God Mode folder.

Moreover, the problem could only be reproduced if the application uses Windows Look and Feel, otherwise GetDisplayNameOf() is not called.

And one more fact to help you understand how the above is connected with Excelsior JET: the implementation of the Java SE standard library included in our product consists, for the most part, of licensed Oracle code. In particular, we reuse the native methods from sun.awt.shell.Win32ShellFolder2 .

This makes all things clear.

The problem is reproduced under rather rare conditions: the O/S is Windows 10 Creators Update, a God Mode folder exists in the system, and the application uses the Windows LAF. That is why we could not reproduce it on our side, and why our tests hadn’t revealed it before release. Deleting the God Mode folder fixes the problem, because that is the only filesystem object for which GetDisplayNameOf() returns a malformed structure. Finally, the problem is present in both the Oracle JRE and Excelsior JET because they share the implementation of the respective native method.

According to the OpenJDK bug tracker, the problem is now fixed and the fix has already been backported to Java 8. It will be included in Excelsior JET automatically when we add support for the respective Java update. This will take some time; I guess we will have some more conversations about God Mode folders with our clients until then, and for some time after.

Thank you for reading! Hope you’ve enjoyed it. Stay tuned for new support stories!

Tags:Java   Windows

标签列表