[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [cp-patches] Bug in java_nio_VMDirectByteBuffer.c
From: |
Archie Cobbs |
Subject: |
Re: [cp-patches] Bug in java_nio_VMDirectByteBuffer.c |
Date: |
Wed, 16 Mar 2005 09:20:49 -0600 |
User-agent: |
Mozilla/5.0 (X11; U; FreeBSD i386; en-US; rv:1.7.3) Gecko/20041129 |
Archie Cobbs wrote:
In gnu_java_awt_peer_gtk_GdkPixbufDecoder.c, in the function
query_formats(), there is a loop where (*env)->NewStringUTF()
is invoked over and over again. There are two bugs actually:
1- The function exhausts the pool of local native references.
It should use DeleteLocalRef() to free them as it goes along.
2- It doesn't check for exceptions from any of the JNI functions
it invokes.
In my case, (*env)->NewStringUTF() threw an exception because of #1,
but the exception was not checked for because of #2, causing an
assertion failure. So just fixing #1 would fix the crash in practice.
For #2 it probably suffices for now to use assert() like is done earlier
in the function after the FindClass() call.
OK, I'm fixing this one too (see attached patch).
-Archie
__________________________________________________________________________
Archie Cobbs * CTO, Awarix * http://www.awarix.com
---
/home/archie/classpath/cvs/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkPixbufDecoder.c
Fri Jan 21 09:16:23 2005
+++ native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkPixbufDecoder.c Wed Mar
16 09:18:18 2005
@@ -206,6 +206,7 @@
jclass formatClass;
jmethodID addExtensionID;
jmethodID addMimeTypeID;
+ jobject string;
formatClass = (*env)->FindClass
(env, "gnu/java/awt/peer/gtk/GdkPixbufDecoder$ImageFormatSpec");
@@ -227,26 +228,33 @@
format = (GdkPixbufFormat *) f->data;
name = gdk_pixbuf_format_get_name(format);
+ string = (*env)->NewStringUTF(env, name);
+ g_assert(string != NULL);
+
jformat = (*env)->CallStaticObjectMethod
- (env, clazz, registerFormatID,
- (*env)->NewStringUTF(env, name),
+ (env, clazz, registerFormatID, string,
(jboolean) gdk_pixbuf_format_is_writable(format));
+ (*env)->DeleteLocalRef(env, string);
g_assert(jformat != NULL);
ch = gdk_pixbuf_format_get_extensions(format);
while (*ch)
{
- (*env)->CallVoidMethod (env, jformat, addExtensionID,
- (*env)->NewStringUTF(env, *ch));
+ string = (*env)->NewStringUTF(env, *ch);
+ g_assert(string != NULL);
+ (*env)->CallVoidMethod (env, jformat, addExtensionID, string);
+ (*env)->DeleteLocalRef(env, string);
++ch;
}
ch = gdk_pixbuf_format_get_mime_types(format);
while (*ch)
{
- (*env)->CallVoidMethod (env, jformat, addMimeTypeID,
- (*env)->NewStringUTF(env, *ch));
+ string = (*env)->NewStringUTF(env, *ch);
+ g_assert(string != NULL);
+ (*env)->CallVoidMethod (env, jformat, addMimeTypeID, string);
+ (*env)->DeleteLocalRef(env, string);
++ch;
}
}