This is the mail archive of the java-patches@gcc.gnu.org mailing list for the Java project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Bug: libjava + cross compiler (ARM) + Runtime.loadLibrary()


I am running a cross compiler toolchain for the ARM processor (iPaq
Linux, Familiar 0.7.2, 2.4.19 kernel).  I used gcc-3.3.2, glibc-2.3.2. 
My desktop machine is an x86_64 system running SuSE GNU/Linux 9.0, 2.6.1
kernel.  I built the full GCC cross compiler toolchain, including gcc,
g++, gcj and all others (which I haven't tried).

Normally, GCC turns off libltdl support for cross compilers.  However, I
needed this for JNI (used by java-gnome, which I compiled for the ARM). 
Therefore, I changed the configure script in my GCC toolchain to enable
this; I did so by commenting out a line that checked for cross
compilers...

  # Only use libltdl for native builds.
  #if test -z "${with_cross_host}"; then

Therefore, USE_LTDL is #define'd to 1 in my cross compiler.  I assumed
that whatever GCC figured out about my SuSE system would probably
transfer to the iPaq and it had a good chance of working.

WELL... it doesn't work; but the problem doesn't seem to have anything
to do with ltdl.  The problem is in natRuntime.cc, part of libjava
(comes with gcj), in the method:

   djava::lang::Runtime::_load (jstring path, jboolean do_search)

That function is given a name of the library (eg: "testlib"), and it
must ultimately figure out a system-dependent full pathname for the
library (eg: "/usr/lib/libtestlib.so").  Somewhere along the line, the
string (char *) containing the name of the library gets munged; this is
before any calls to ltdl are made.

Specifically, consider Figure 1 below, which is an excerpt from
natRuntime.cc with debugging printout added.  I receive the debugging
output of Figure 2 when run on the ARM (see Figure 2).  As you can see,
the creation of the ArrayIndexOutOfBoundsException somehow kills the C++
stack variable buf.  The same program works fine when compiled native.

I have a small test program that allows one to modify System.java,
Runtime.java, natSystem.cc and natRuntime.cc, in order to test and debug
this problem.  My test program verifies that everything works fine under
native, but messes up on the ARM processor.

Does anyone know what the bug might be?  Maybe some oversight in the ARM
stack handling or something?  I can send or post my test program to
anyone who's interested.  (Unfortuantely, it's still a few hundred
KBytes, due to all the extra stuff that must be included to get this
little excerpt to compile).

Thanks,
-- Bob

-----------------------------------------------------------
Figure 1
========
void
djava::lang::Runtime::_load (jstring path, jboolean do_search)
{
  JvSynchronize sync (this);
  using namespace java::lang;

java::lang::System::out->println(path);

#ifdef USE_LTDL
  jint len = _Jv_GetStringUTFLength (path);
  char buf[len + 1 + strlen (_Jv_platform_solib_prefix)
	   + strlen (_Jv_platform_solib_suffix)];
  int offset = 0;
  if (do_search)
    {
      strcpy (buf, _Jv_platform_solib_prefix);
      offset = strlen (_Jv_platform_solib_prefix);
    }
  jsize total = JvGetStringUTFRegion (path, 0, path->length(),
&buf[offset]);
  buf[offset + total] = '\0';

  char *lib_name = buf;
printf("BB %s\n",lib_name);

  if (do_search)
    {
printf("B1 %s\n",lib_name);
      ClassLoader *sys = ClassLoader::getSystemClassLoader();
printf("B1 %s\n",lib_name);
      ClassLoader *look = NULL;
printf("B1 %s\n",lib_name);
      gnu::gcj::runtime::StackTrace *t = new
gnu::gcj::runtime::StackTrace(10);
printf("B1 %s\n",lib_name);
      try
      	{
	  for (int i = 0; i < 10; ++i)
	    {
printf("B2 %d %s\n",i, lib_name);
	      jclass klass = t->classAt(i);
printf("B2a %s\n",lib_name);
	      if (klass != NULL)
		{
printf("B3 %s\n",lib_name);
		  ClassLoader *loader = klass->getClassLoaderInternal();
		  if (loader != NULL && loader != sys)
		    {
		      look = loader;
		      break;
		    }
		}
	    }
	}
      catch (::java::lang::ArrayIndexOutOfBoundsException *e)
	{
printf("BE %s\n",lib_name);
	}
printf("BX %s\n",lib_name);

      if (look != NULL)
	{
	  // Don't include solib prefix in string passed to
	  // findLibrary.
	  jstring name = look->findLibrary(JvNewStringUTF(&buf[offset]));
	  if (name != NULL)
	    {
	      len = _Jv_GetStringUTFLength (name);
	      lib_name = (char *) _Jv_AllocBytes(len + 1);
	      total = JvGetStringUTFRegion (name, 0,
					    name->length(), lib_name);
	      lib_name[total] = '\0';
	      // Don't append suffixes any more; we have the full file
	      // name.
	      do_search = false;
	    }
	}
    }

  lt_dlhandle h;
  // FIXME: make sure path is absolute.
  {
    // Synchronize on java.lang.Class. This is to protect the class
chain from
    // concurrent modification by class registration calls which may be
run
    // during the dlopen().
    JvSynchronize sync (&java::lang::Class::class$);
printf("CC %s\n",lib_name); 
   h = do_search ? lt_dlopenext (lib_name) : lt_dlopen (lib_name);
  }
----------------------------------------------------------
Figure 2
========
/mnt/ramfs # ./Test-arm
Hello2
dHello
testlib
BB libtestlib
B1 libtestlib
B1 libtestlib
B1 libtestlib
B1 libtestlib
B2 0 libtestlib
B2a libtestlib
B2 1 libtestlib
B2a libtestlib
B2 2 libtestlib
B2a libtestlib
B2 3 libtestlib
B2a libtestlib
B2 4 libtestlib
B2a libtestlib
B2 5 libtestlib
B2a libtestlib
B2 6 libtestlib
B2a libtestlib
B2 7 libtestlib
BE >
BX
   >
CC >



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]