Skip to content

JVM crashes when finalizer tries to close dataset #12764

@opeongo

Description

@opeongo

What is the bug?

Using the Java bindings to GDAL 3.11.3, the JVM will crash when the Dataset finalizer runs and trys to close the Dataset object. Stack traces often look like the following:

Current thread (0x0000018bc00ef160):  JavaThread "Finalizer" daemon [_thread_in_native, id=22988, stack(0x0000006f4eb00000,0x0000006f4ec00000) (1024K)]

Stack: [0x0000006f4eb00000,0x0000006f4ec00000],  sp=0x0000006f4ebff220,  free space=1020k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
C  [gdal.dll+0x549dc7]

Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
j  org.gdal.gdal.gdalJNI.delete_Dataset(J)V+0
j  org.gdal.gdal.Dataset.delete()V+25
j  org.gdal.gdal.Dataset.finalize()V+1
j  java.lang.System$2.invokeFinalize(Ljava/lang/Object;)V+1 [email protected]
j  java.lang.ref.Finalizer.runFinalizer(Ljdk/internal/access/JavaLangAccess;)V+115 [email protected]
j  java.lang.ref.Finalizer$FinalizerThread.run()V+29 [email protected]
v  ~StubRoutines::call_stub 0x0000018b759f100d

siginfo: EXCEPTION_ACCESS_VIOLATION (0xc0000005), reading address 0x0000000000000070

The problem is intermittent: most often the crash will occur but sometimes it does not. Most often the stack trace is like the above, sometimes it crashes elsewhere in the Java libraries making it look like the heap is being corrupted.

Steps to reproduce the issue

The following sample program frequently triggers this problem:

import org.gdal.gdal.Band;
import org.gdal.gdal.Dataset;
import org.gdal.gdal.Driver;
import org.gdal.gdal.gdal;

import static org.gdal.gdalconst.gdalconstConstants.GDT_Int32;

public class GdalCrashJvm {
    public static void main(String[] args) {

        gdal.AllRegister();
        Driver drv = gdal.GetDriverByName("GTiff");
        Dataset ds = drv.Create("c:/tmp/test2.tif", 10, 10, 1, GDT_Int32, new String[]{});
        Band bd = ds.GetRasterBand(1);
        System.err.println("First closing");
        bd.GetDataset().Close();
        ds = null;
        bd = null;
        System.gc();

        ds = gdal.Open("c:/tmp/test2.tif");
        bd = ds.GetRasterBand(1);
        System.err.println("Second closing");
        bd.GetDataset().Close();
        ds = null;
        bd = null;
        System.gc();
        System.gc();
        try {
            Thread.sleep(2000);
        } catch (Exception ignore) {
        }
    }
}

Versions and provenance

OS Windows 11 Pro 2H2 Build 22000.556
GDAL 3.11.3 pulled from github and built using conda as per instructions at https://gdal.org/en/stable/development/dev_environment.html
Java version 21

Additional context

As I built the small self contained example I noted that the error would not happen if I closed the Dataset object using the Dataset.Close() method. However, when I closed the dataset using Band.GetDataset().Close() the error will frequently occur.

My workaround for this problem is to close the dataset using Dataset.Close() instead of Band.GetDataset().Close(). I am reporting this to let you know of the issue which may have other implications. Even though Band.GetDataset().Close() is not a preferred way of doing things, it really should not be leading to crashing the JVM.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions