Debugging libgcj on cygwin

Thomas Pfaff tpfaff@gmx.net
Mon Jun 30 08:03:00 GMT 2003


Thomas Pfaff wrote:

Replying to myself:

> Hi all,
> 
> i try to create gcj on cygwin. Gcc is gcc 3.3 with a cygwin-mingw 
> specific patch from Danny Smith and configured with
> 
> ../gcc-3.3/configure --prefix=/usr/gcc-3.3 --enable-sjlj-exceptions 
> --disable-shared --enable-threads=posix --enable-languages=c,c++,java 
> --enable-libgcj --disable-nls --target=i686-cygwin --host=i686-cygwin 
> --with-gcc --with-gnu-ld --with-gnu-as --disable-win32-registry 
> --without-included-gettext --with-system-zlib 
> --disable-version-specific-runtime-libs --enable-haifa --enable-interpreter
> 
> Building gcj went fine, running the testsuite however results in 
> segmentation faults on every compiled app. The backtrace is always the 
> same for any app:
> 
> Program received signal SIGSEGV, Segmentation fault.
> _Jv_InterpMethod::run(void*, ffi_raw*) (this=0x1014be60, retp=0x22f730, 
> args=0x22f750) at ../../../gcc-3.3/libjava/include/java-interp.h:230
> 230         next = *n;
> 
> which is located at java-interp.h:230
> 
>   _Jv_MethodChain (const _Jv_InterpMethod *s, _Jv_MethodChain **n)
>   {
>     self = s;
>     ptr = n;
>     next = *n;
>     *n = this;
>   }
> 
> (gdb) bt
> #0  _Jv_InterpMethod::run(void*, ffi_raw*) (this=0x1014be60, 
> retp=0x22f730, args=0x22f750) at 
> ../../../gcc-3.3/libjava/include/java-interp.h:230
> #1  0x0022f698 in ?? ()
> #2  0x00461e7a in ffi_closure_raw_SYSV (closure=0x0) at 
> ../../../gcc-3.3/libffi/src/x86/ffi.c:379
> #3  0x0040e219 in java::lang::Class::newInstance() (this=0x10148e80) at 
> ../../../gcc-3.3/libjava/java/lang/natClass.cc:719
> #4  0x00463973 in 
> gnu.gcj.convert.UnicodeToBytes.getEncoder(java.lang.String) 
> (encoding=0x10130c60) at 
> ../../../gcc-3.3/libjava/gnu/gcj/convert/UnicodeToBytes.java:96
> #5  0x004635b0 in gnu.gcj.convert.UnicodeToBytes.getDefaultEncoder() () 
> at ../../../gcc-3.3/libjava/gnu/gcj/convert/UnicodeToBytes.java:62
> #6  0x0043635e in java.io.PrintStream.PrintStream(java.io.OutputStream, 
> boolean) (this=0x10130c80, out=0x10144678, af=269684225) at 
> ../../../gcc-3.3/libjava/java/io/PrintStream.java:241
> #7  0x0040661c in java.lang.System.<clinit>() () at 
> ../../../gcc-3.3/libjava/java/lang/System.java:135
> #8  0x0040e47d in java::lang::Class::initializeClass() (this=0x54dc10) 
> at ../../../gcc-3.3/libjava/java/lang/natClass.cc:814
> #9  0x00406008 in java.lang.System.getProperty(java.lang.String) 
> (key=0x10131f00) at ../../../gcc-3.3/libjava/java/lang/System.java:393
> #10 0x004154e3 in java.lang.Throwable.<clinit>() () at 
> ../../../gcc-3.3/libjava/java/lang/Throwable.java:403
> #11 0x0040e47d in java::lang::Class::initializeClass() (this=0x550250) 
> at ../../../gcc-3.3/libjava/java/lang/natClass.cc:814
> #12 0x0040e4d0 in java::lang::Class::initializeClass() (this=0x54dd70) 
> at ../../../gcc-3.3/libjava/java/lang/Class.h:265
> #13 0x0040e4d0 in java::lang::Class::initializeClass() (this=0x557a10) 
> at ../../../gcc-3.3/libjava/java/lang/Class.h:265
> #14 0x0040e4d0 in java::lang::Class::initializeClass() (this=0x54eff0) 
> at ../../../gcc-3.3/libjava/java/lang/Class.h:265
> #15 0x00402a93 in _Jv_AllocObjectNoFinalizer (klass=0x54eff0, size=24) 
> at ../../../gcc-3.3/libjava/java/lang/Class.h:265
> #16 0x00402abe in _Jv_AllocObject (klass=0x54eff0, size=24) at 
> ../../../gcc-3.3/libjava/prims.cc:415
> #17 0x00403a10 in _Jv_CreateJavaVM(void*) () at 
> ../../../gcc-3.3/libjava/prims.cc:921
> #18 0x00403c52 in _Jv_RunMain(java::lang::Class*, char const*, int, char 
> const**, bool) (klass=0x54d0b0, name=0x0, argc=1, argv=0x101023f8, 
> is_jar=false) at ../../../gcc-3.3/libjava/prims.cc:973
> #19 0x00403e1f in JvRunMain (klass=0x54d0b0, argc=1, argv=0x101023f8) at 
> ../../../gcc-3.3/libjava/prims.cc:1011
> #20 0x0040108c in main (argc=1, argv=0x101023f8) at 
> /c/DOKUME~1/pfaff/LOKALE~1/Temp/ccIEfgxx.i:11
> 
> It seems that n does not contain a valid address.
> This happens only if the app is running from a different directory 
> (testsuite/Final.exe for example), if it is called from the same 
> directory (./Final.exe) it works.
> 

After some debug sessions i think that i got the problem:

When running the testsuite from the libjava directory
gnu.gcj.convert.UnicodeToBytes.getDefaultEncoder() tries to load the
encoder class for "gnu.gcj.convert.Output_ASCII". It will search for
this class on the filesystem first and sees that a class exists at
"./gnu/gcj/convert/Output_ASCII.class".

An attempt to load and run this class via _Jv_InterpMethod::run is made.
A call to java::lang::Thread *thread = java::lang::Thread::currentThread
is made which returns NULL since the main thread is not initialized yet
(a call to _Jv_AttachCurrentThread will be later done in _Jv_RunMain,
the backtrace above shows that it is still in _Jv_CreateJavaVM).

What makes me wonder is that this seems to happen only on cygwin.

I have created a small patch to URLClassLoader.java

--- URLClassLoader.java.org	2003-01-02 10:36:05.000000000 +0100
+++ URLClassLoader.java	2003-06-30 09:54:03.000000000 +0200
@@ -756,6 +756,12 @@ public class URLClassLoader extends Secu
    protected Class findClass(final String className)
      throws ClassNotFoundException
    {
+    // Do not try to load a class from URL
+    // until the calling thread is registered
+    Thread current = Thread.currentThread();
+    if (current == null)
+      throw new ClassNotFoundException(className + " not found in " + 
urls);
+
      // Just try to find the resource by the (almost) same name
      String resourceName = className.replace('.', '/') + ".class";
      Resource resource = findURLResource(resourceName);

With this patch the test result was

Running /usr/src/gcc-3/gcc-3.3/libjava/testsuite/libjava.lang/lang.exp ...
FAIL: Array_3 execution - source compiled test
FAIL: Array_3 execution - bytecode->native test
FAIL: Array_3 -O execution - source compiled test
FAIL: Array_3 -O execution - bytecode->native test
FAIL: Divide_1 execution - source compiled test
FAIL: Divide_1 execution - bytecode->native test
FAIL: Divide_1 -O execution - source compiled test
FAIL: Divide_1 -O execution - bytecode->native test
FAIL: SyncTest execution - bytecode->native test
FAIL: SyncTest -O execution - bytecode->native test
FAIL: TLtest execution - source compiled test
FAIL: TLtest output - bytecode->native test
FAIL: TLtest -O execution - source compiled test
FAIL: TLtest -O execution - bytecode->native test
FAIL: TestProxy execution - source compiled test
FAIL: TestProxy execution - bytecode->native test
FAIL: TestProxy -O execution - source compiled test
FAIL: TestProxy -O execution - bytecode->native test
FAIL: Thread_Alive execution - source compiled test
FAIL: Thread_Alive execution - bytecode->native test
FAIL: Thread_Alive -O execution - source compiled test
FAIL: Thread_Alive -O execution - bytecode->native test
FAIL: Thread_Join execution - source compiled test
FAIL: Thread_Join execution - bytecode->native test
FAIL: Thread_Join -O execution - source compiled test
FAIL: Thread_Join -O execution - bytecode->native test
FAIL: Thread_Wait_2 execution - source compiled test
FAIL: Thread_Wait_2 execution - bytecode->native test
FAIL: Thread_Wait_2 -O execution - source compiled test
FAIL: Thread_Wait_2 -O execution - bytecode->native test
FAIL: Thread_Wait_Interrupt execution - source compiled test
FAIL: Thread_Wait_Interrupt execution - bytecode->native test
FAIL: Thread_Wait_Interrupt -O execution - source compiled test
FAIL: Thread_Wait_Interrupt -O execution - bytecode->native test
FAIL: Throw_2 execution - source compiled test
FAIL: Throw_2 execution - bytecode->native test
FAIL: Throw_2 -O execution - source compiled test
FAIL: Throw_2 -O execution - bytecode->native test
Running 
/usr/src/gcc-3/gcc-3.3/libjava/testsuite/libjava.loader/loader.exp ...
FAIL: 
/usr/src/gcc-3/BUILD.cygwin/i686-cygwin/libjava/testsuite/TestEarlyGC.exe 
output - /usr/src/gc
c-3/BUILD.cygwin/i686-cygwin/libjava/testsuite/TestEarlyGC.exe
FAIL: 
/usr/src/gcc-3/BUILD.cygwin/i686-cygwin/libjava/testsuite/TestLeak.exe 
execution - /usr/src/gc
c-3/BUILD.cygwin/i686-cygwin/libjava/testsuite/TestLeak.exe
FAIL: 
/usr/src/gcc-3/BUILD.cygwin/i686-cygwin/libjava/testsuite/TestMultiple.exe 
execution - /usr/sr
c/gcc-3/BUILD.cygwin/i686-cygwin/libjava/testsuite/TestMultiple.exe
FAIL: 
/usr/src/gcc-3/BUILD.cygwin/i686-cygwin/libjava/testsuite/TestParent.exe 
execution - /usr/src/
gcc-3/BUILD.cygwin/i686-cygwin/libjava/testsuite/TestParent.exe
Running /usr/src/gcc-3/gcc-3.3/libjava/testsuite/libjava.mauve/mauve.exp ...

                 === libjava Summary ===

# of expected passes            2343
# of unexpected failures        55
# of expected failures          29
# of untested testcases         52


The java interpreter seems to have a similar problem, therefore i
configured with --disable-interpreter, the jni tests have also failed.

Thomas




More information about the Java mailing list