Bug 15001 - [3.4 only] Using JNI with interpreter and interface methods yields SIGSEGV
Summary: [3.4 only] Using JNI with interpreter and interface methods yields SIGSEGV
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: libgcj (show other bugs)
Version: 3.4.0
: P2 normal
Target Milestone: 3.4.4
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2004-04-18 09:29 UTC by Thomas Hallgren
Modified: 2005-01-18 20:37 UTC (History)
2 users (show)

See Also:
Host: i86-pc-linux-gnu
Target:
Build:
Known to work: 4.0.0
Known to fail:
Last reconfirmed: 2004-05-25 22:09:41


Attachments
Sample code (8.21 KB, application/x-gzip)
2004-04-18 09:31 UTC, Thomas Hallgren
Details
Patch to add a test case (653 bytes, patch)
2004-09-21 18:11 UTC, Tom Tromey
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Thomas Hallgren 2004-04-18 09:29:54 UTC
When using JNI to call an interpreted method who's jmethodID stems from an
interface, the program receives a SIGSEGV. The signal handler in turn, goes into
an endless unwind loop and the program appears to be hung.

The sample program uses JNI to instantiate the "jvm", obtains the interface and
implementation class, instantiates the latter and tries to call a method on it.
First it uses a jmethodID obtained directly from the implementation class. That
succeeds. Then, it uses the jmethodID it gets when obtaining the same method
from the implemented interface. That fails.

I know that sending a compressed tar file is against your policy, but you do
need the .class files in order to reproduce this bug.
Comment 1 Thomas Hallgren 2004-04-18 09:31:59 UTC
Created attachment 6109 [details]
Sample code
Comment 2 Tom Tromey 2004-04-18 17:43:19 UTC
I suspect this bug was fixed by this:

2004-04-14  Andrew Haley  <aph@redhat.com>
            Bryce McKinlay  <mckinlay@redhat.com>

	* java/lang/reflect/natMethod.cc (_Jv_CallAnyMethodA): Use
	_Jv_LookupInterfaceMethodIdx for calls to interfaces.
	* include/jvm.h (_Jv_CallAnyMethodA): Add new `iface' arg.

	* testsuite/libjava.lang/InvokeInterface.java: New file.
	* testsuite/libjava.lang/InvokeInterface.out: New file.


This is only on cvs head, not in 3.4.
I've set the target milestone to 3.4.1 to indicate that we should
back-port this fix once 3.4.0 ships.

Comment 3 Andrew Pinski 2004-04-19 02:59:26 UTC
Confirmed.
Comment 4 Bryce McKinlay 2004-05-25 22:09:17 UTC
Actually this isn't restricted to 3.4, the problem occurs on mainline as well.
Comment 5 Mark Mitchell 2004-06-05 20:34:23 UTC
Postponed until 3.4.2, unless someone fixes it sooner...
Comment 6 Mark Mitchell 2004-08-19 20:48:40 UTC
Postponed until GCC 3.4.3.
Comment 7 Bryce McKinlay 2004-09-09 16:03:05 UTC
I'll look into the status of this for the 3.4 branch. AFAIK, Interface calls via
JNI are still broken even on mainline. This patch only fixes it for reflection.
Perhaps we should put the old, non-index based code back in for the 3.4 branch,
and come up with a real fix for mainline.
Comment 8 Tom Tromey 2004-09-21 18:11:27 UTC
Created attachment 7185 [details]
Patch to add a test case
Comment 9 Tom Tromey 2004-09-21 18:19:57 UTC
I looked at this a little, and wrote a test case
that can be checked in whenever we're ready.

This code is sort of a mess.  A jmethodID doesn't
have a pointer back to its declaring class, so
we don't have an easy way to tell whether or not
it came from an interface.

We could search the "receiver" object's class hierarchy
for the concrete method and use that, but this is
inefficient.

One question I have is why method->index is not -1 for
a method declared in an interface.  Perhaps declaring that
this must be -1 for such methods is the simplest fix.
Currently this is supposed to contain the dispatch index,
but I don't see that we ever use that.

Another approach would be to add a new flag to method->accflags
indicating that it is an interface method.  This is a hack, but
would work.  It would require going over bits of the runtime to
ensure that we mask this bit out as appropriate, e.g. when adding
Miranda methods to the concrete class hierarchy.
Comment 10 Mark Mitchell 2004-11-01 00:44:43 UTC
Postponed until GCC 3.4.4.
Comment 11 Bryce McKinlay 2004-12-10 05:47:02 UTC
meth->index for an interface method should contain the IDT dispatch index for
that method, which allows us to use fast interface dispatch
(_Jv_LookupInterfaceMethodIdx) for Method.invoke() calls. Unfortunately, this
index is useless without also knowing which interface the method belongs to, and
as Tom points out, we do not currently have a way to get from a JNI jMethodID to
the interface, hence this PR.

Perhaps a special flag for interface methods would be the best fix in the short
term, until we can somehow fix JNI to give us a class/interface from a jMethodID.
Comment 12 GCC Commits 2004-12-17 15:13:53 UTC
Subject: Bug 15001

CVSROOT:	/cvs/gcc
Module name:	gcc
Changes by:	aph@gcc.gnu.org	2004-12-17 15:13:44

Modified files:
	libjava        : ChangeLog 
	libjava/java/lang/reflect: natMethod.cc 

Log message:
	2004-12-10  Andrew Haley  <aph@redhat.com>
	
	PR java/15001
	* java/lang/reflect/natMethod.cc (_Jv_CallAnyMethodA): Look up
	abstract methods by name.

Patches:
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libjava/ChangeLog.diff?cvsroot=gcc&r1=1.3261&r2=1.3262
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libjava/java/lang/reflect/natMethod.cc.diff?cvsroot=gcc&r1=1.42&r2=1.43

Comment 13 GCC Commits 2004-12-21 00:49:51 UTC
Subject: Bug 15001

CVSROOT:	/cvs/gcc
Module name:	gcc
Changes by:	tromey@gcc.gnu.org	2004-12-21 00:49:46

Modified files:
	libjava        : ChangeLog 
Added files:
	libjava/testsuite/libjava.jni: iface.c iface.java iface.out 

Log message:
	PR java/15001
	* testsuite/libjava.jni/iface.c: New file.
	* testsuite/libjava.jni/iface.out: New file.
	* testsuite/libjava.jni/iface.java: New file.

Patches:
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libjava/ChangeLog.diff?cvsroot=gcc&r1=1.3263&r2=1.3264
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libjava/testsuite/libjava.jni/iface.c.diff?cvsroot=gcc&r1=NONE&r2=1.1
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libjava/testsuite/libjava.jni/iface.java.diff?cvsroot=gcc&r1=NONE&r2=1.1
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libjava/testsuite/libjava.jni/iface.out.diff?cvsroot=gcc&r1=NONE&r2=1.1

Comment 14 Tom Tromey 2005-01-18 20:37:29 UTC
Fix checked in.