Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4622892

FileSystemView.getSystemIcon crashes Windows

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Duplicate
    • Icon: P4 P4
    • None
    • 1.4.0, 1.4.1
    • client-libs
    • x86
    • windows_98, windows_xp



      Name: jk109818 Date: 01/11/2002


      FULL PRODUCT VERSION :
      java version "1.4.0-beta3"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-beta3-b84)
      Java HotSpot(TM) Client VM (build 1.4.0-beta3-b84, mixed mode)


      FULL OPERATING SYSTEM VERSION :

      Windows Millennium [Version 4.90.3000]



      A DESCRIPTION OF THE PROBLEM :
      FileSystemView.getSystemIcon is not releasing GDI resources
      back to Windows, which causes the system to crash after
      repeated invocations (even spread across different runs).

      I first noticed this problem in a real program, so it
      doesn't take an artificial testcase like this for it to
      occur. A few runs of a Java program which uses system
      icons can exhaust GDI memory and force a reboot.


      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Compile and run the attached testcase on a Windows system.
      I'm on Windows ME, but I highly doubt that it makes a
      difference.

      The testcase will attempt to get icons for every file on
      your system. It frequently forces the garbage collector to
      run just to prove that that doesn't help.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      Expected result: Testcase prints a bunch of periods and
      exits normally.

      Actual result: After a minute or so, your system should
      have crashed in one of a variety of ways. I have seen
      everything from the program simply hanging (but due to no
      GDI resources you get an error message if you try to start
      any other programs) to shutting my system down (as in I
      saw, for no apparent reason, "It is now safe to turn off
      your computer" and then the computer turned itself off).

      This bug can be reproduced always.


      ---------- BEGIN SOURCE ----------

      import java.io.*;
      import javax.swing.filechooser.*;

      public class TestCase {
          static int count;
          private static FileSystemView fileSystemView = FileSystemView.getFileSystemView();
          
          public static void scanDirectory(File parent) {
              File[] files = parent.listFiles();
              if (files == null)
                  return;
              for (int i = 0; i < files.length; i++) {
                  if (files[i].isDirectory())
                      scanDirectory(files[i]);
                  else {
                      try {
                          fileSystemView.getSystemIcon(files[i]);
                          System.out.print(".");
                      }
                      catch (Exception e) { /* ignore */ }
                  }
                  if (++count >= 10) {
                      count = 0;
                      // gc and sleep just to prove finalizer doesn't help
                      System.gc();
                      try { Thread.sleep(100); } catch (InterruptedException e) { }
                  }
              }
          }
          
          
          public static void main(String[] arg) {
              File[] roots = fileSystemView.getRoots();
              for (int i = 0; i < roots.length; i++)
                  scanDirectory(roots[i]);
          }
      }



      ---------- END SOURCE ----------
      (Review ID: 138198)
      ======================================================================

      Name: rmT116609 Date: 01/16/2003


      FULL PRODUCT VERSION :
      java version "1.4.1_01"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.1_01-b01)
      Java HotSpot(TM) Client VM (build 1.4.1_01-b01, mixed mode)

      FULL OPERATING SYSTEM VERSION :
      Microsoft Windows XP [Version 5.1.2600]

      ADDITIONAL OPERATING SYSTEMS :
      All of Windows platform

      A DESCRIPTION OF THE PROBLEM :
      Win32ShellFolder.getIconBits() is not releasing GDI resources.
      It's copy of Bug ID 4622892. I wrote the patch of this bug to
      http://developer.java.sun.com/developer/bugParade/bugs/4622892.html. however there is no reaction.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Compile and run the attached test on a Windows system. If implemented correctly, all GDI resources are released correctly. However GDI resources are not released. You can check it by TaskManager of Windows(see GDI Object).


      EXPECTED VERSUS ACTUAL BEHAVIOR :
      Expected result : print "success." at last.

      Actual result : print "used up GDI resources." at count 5000(on WindowsXP, in the case of Win9x, used up GDI resources at a fewer count.)


      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      import java.io.File;
      import java.io.FileNotFoundException;
      import java.awt.Image;
      import sun.awt.shell.ShellFolder;

      public class test{
      private static int count;

      public static void main(String[] args){
      File[] roots = File.listRoots();
      count = 0;

      for(int i = 0; i < roots.length; i++){
      try{
                       ShellFolder shell = ShellFolder.getShellFolder( roots[i] ); Image icon = shell.getIcon(false);
      System.out.println((++count) + " " + icon);
      if( icon == null ){
      System.out.println( "used up GDI resources." );
      System.exit( 1 );
      }
      }catch( FileNotFoundException exception ){
      }
      func(roots[i]);
      }
      System.out.println( "success." );
      }

      private static void func(File dir){
      File[] files = dir.listFiles();
      if(files != null){
      for(int i = 0; i < files.length; i++){
      try{
      ShellFolder shell = ShellFolder.getShellFolder( files[i] );
      Image icon = shell.getIcon(false);
      System.out.println((++count)+ " " + icon);
      if( icon == null ){
      System.out.println "used up GDI resources." );
      System.exit( 1 );
      }
       }catch( FileNotFoundException exception ){
      }
      if(files[i].isDirectory()){
      func(files[i]);
      }
      }
      }
      }
      }


      ---------- END SOURCE ----------

      SUGGESTED FIX :
      the following is not work around. It's the debuging method of this bug.

      Please
      correct /j2se/src/win32/native/sun/windows/ShellFolder.cpp
      as follows

      JNIEXPORT jintArray JNICALL
      Java_sun_awt_shell_Win32ShellFolder_getIconBits
          (JNIEnv* env, jobject folder, jlong hicon, jint
      iconSize)
      {
          // Get the icon info
          ICONINFO iconInfo;
          if (!fn_GetIconInfo((HICON)hicon, &iconInfo)) {
              return NULL;
          }
          // Get the screen DC
          HDC dc = GetDC(NULL);
          if (dc == NULL) {
              DeleteObject( iconInfo.hbmColor ); //add
              DeleteObject( iconInfo.hbmMask ); //add
              return NULL;
          }
          // Set up BITMAPINFO
          BITMAPINFO bmi;
          memset(&bmi, 0, sizeof(BITMAPINFO));
          bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
          bmi.bmiHeader.biWidth = iconSize;
          bmi.bmiHeader.biHeight = -iconSize;
          bmi.bmiHeader.biPlanes = 1;
          bmi.bmiHeader.biBitCount = 32;
          bmi.bmiHeader.biCompression = BI_RGB;
          // Extract the color bitmap
          int nBits = iconSize * iconSize * 32 / 8;
          long colorBits[4096];
          GetDIBits(dc, iconInfo.hbmColor, 0, iconSize,
      colorBits, &bmi, DIB_RGB_COLORS);
          // Extract the mask bitmap
          long maskBits[4096];
          GetDIBits(dc, iconInfo.hbmMask, 0, iconSize, maskBits,
      &bmi, DIB_RGB_COLORS);
          // Copy the mask alphas into the color bits
          for (int i = 0; i < nBits; i++) {
              colorBits[i] = colorBits[i] | ((maskBits[i] !=
      0) ? 0 : 0xff000000);
          }
          // Release DC
          ReleaseDC(NULL, dc);
          // Release bitmap handle in icon info
          DeleteObject( iconInfo.hbmColor ); //add
          DeleteObject( iconInfo.hbmMask ); //add
          // Create java array
          jintArray iconBits = env->NewIntArray(nBits);
          // Copy values to java array
          env->SetIntArrayRegion(iconBits, 0, nBits, colorBits);
          return iconBits;
      }

      I think that fllowing is also foreget releasing the GDI
      resource, please correct it.

      JNIEXPORT jlong JNICALL
      Java_sun_awt_shell_Win32ShellFolder_getIcon__JJZ
          (JNIEnv* env, jobject folder, jlong
      parentIShellFolder, jlong
      relativePIDL,
           jboolean getLargeIcon)
      {
          IShellFolder* pParent = (IShellFolder*)
      parentIShellFolder;
          if (pParent == NULL) {
              return 0;
          }
          LPITEMIDLIST pidl = (LPITEMIDLIST)relativePIDL;
          if (pidl == NULL) {
              return 0;
          }
          IExtractIcon* pIcon;
          if (pParent->GetUIObjectOf(NULL, 1,
      const_cast<LPCITEMIDLIST*>(&pidl),
              IID_IExtractIcon, NULL, (void**)&pIcon) != S_OK) {
              return 0;
          }
          CHAR szBuf[MAX_PATH];
          INT index;
          UINT flags;
          if (pIcon->GetIconLocation(
              GIL_FORSHELL, szBuf, MAX_PATH, &index, &flags)
              != S_OK) {
              pIcon->Release();
              return 0;
          }
          HICON hIcon;
          HICON hIconLarge;
          if (pIcon->Extract(szBuf, index, &hIconLarge, &hIcon,
      (16 << 16) + 32) != S_OK) {
              pIcon->Release();
              return 0;
          }

          //return (jlong)(getLargeIcon ? hIconLarge : hIcon);
          pIcon->Release(); //add
          if (getLargeIcon){ //add
              DestroyIcon(hIcon); //add
              return (jlong)hIconLarge; //add
          }else{ //add
              DestroyIcon(hIconLarge); //add
              return (jlong)hIcon; //add
          } //add
      }
      (Review ID: 180015)
      ======================================================================

            leifs Leif Samuelsson (Inactive)
            jkimsunw Jeffrey Kim (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: