* [PATCH PR42811,4.5 regression] java.lang.ExceptionInInitializerError in ecj1 @ 2010-02-05 22:09 Dave Korn 2010-02-06 6:12 ` Dave Korn 0 siblings, 1 reply; 6+ messages in thread From: Dave Korn @ 2010-02-05 22:09 UTC (permalink / raw) To: Java Patches, GCC Patches [-- Attachment #1: Type: text/plain, Size: 1392 bytes --] http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42811 Hi lists, In this PR, ecj1 is failing (on Cygwin, presumably MinGW as well) owing to unintended fallout from building libgcj as two separate DLLs. There are only static dependencies (i.e. unresolved symbols in the ecj.o object) for ecjx to pull in the main libgcj at linktime, so only that DLL gets loaded into memory at runtime. But the class loader wants to load something from the subsidiary (-noncore) DLL, and it's not present in memory, so it fails. (IIUC this is what the class definition data that is stored in .jcr sections and made available to the class loader through a a .ctor-like mechanism in the crtbegin code is all about.) In this patch, I add an arbitrary undef to the link spec, against a fairly randomly chosen symbol (my only criterion was that the org.ietf.jgss namespace is probably fairly stable) from the -noncore part of the library. This sufficed to build an ecjx that links against and hence loads both DLLs, and it doesn't throw the exception shown in the PR anymore. libjava/ChangeLog: PR java/42811 * configure.ac (libgcj_spec_lgcj_override): Add undefined reference to arbitrary symbol in noncore library. (libgcj_spec_lgcj_bc_override): Likewise. I'm taking this for a bootstrap-and-test cycle on i686-pc-cygwin. Does it seem like a reasonable approach? cheers, DaveK [-- Attachment #2: pr42811.diff --] [-- Type: text/x-c, Size: 1104 bytes --] Index: libjava/configure.ac =================================================================== --- libjava/configure.ac (revision 156467) +++ libjava/configure.ac (working copy) @@ -244,9 +244,13 @@ if test "$enable_libgcj_sublibs" = yes ; then # tag "_bc" onto the end of it when we use it to generate the # spec, but that's an ugly thing to do when there are multiple # words in the string and you're relying on the ordering to - # append the correct one. - libgcj_spec_lgcj_override="-lgcj-noncore -lgcj" - libgcj_spec_lgcj_bc_override="-lgcj-noncore -lgcj_bc" + # append the correct one. Note that we add an arbitrary undef + # from libgcj-noncore to ensure the library is actually linked + # and loaded, as there aren't static dependencies to tell us + # which classes will be loaded at runtime, so we need to ensure + # that all the class data (.jcr sections) are present and initialised. + libgcj_spec_lgcj_override="-lgcj-noncore -u__ZN3org4ietf4jgss10GSSManagerC1Ev -lgcj" + libgcj_spec_lgcj_bc_override="-lgcj-noncore -u__ZN3org4ietf4jgss10GSSManagerC1Ev -lgcj_bc" fi ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH PR42811,4.5 regression] java.lang.ExceptionInInitializerError in ecj1 2010-02-05 22:09 [PATCH PR42811,4.5 regression] java.lang.ExceptionInInitializerError in ecj1 Dave Korn @ 2010-02-06 6:12 ` Dave Korn 2010-02-15 2:49 ` [REVIVED: PATCH " Dave Korn 0 siblings, 1 reply; 6+ messages in thread From: Dave Korn @ 2010-02-06 6:12 UTC (permalink / raw) To: Dave Korn; +Cc: Java Patches, GCC Patches On 05/02/2010 22:26, Dave Korn wrote: > libjava/ChangeLog: > > PR java/42811 > * configure.ac (libgcj_spec_lgcj_override): Add undefined reference > to arbitrary symbol in noncore library. > (libgcj_spec_lgcj_bc_override): Likewise. > > I'm taking this for a bootstrap-and-test cycle on i686-pc-cygwin. Does it > seem like a reasonable approach? It caused a regression: > FAIL: events output For some reason, a couple of extra jvm event callbacks appeared: > $ diff -pu events.out .e.o > --- events.out 2009-03-14 06:47:02.984375000 +0000 > +++ .e.o 2010-02-06 06:04:50.218750000 +0000 > @@ -4,9 +4,9 @@ created JVMTI environment #0 > created JVMTI environment #1 > created JVMTI environment #2 > setting callbacks for envs > -RequestedEvents: > +RequestedEvents: VMInit,VMDeath, > enable VM_INIT for env0, env1, env2 > -RequestedEvents: VMInit, > +RequestedEvents: VMInit,VMDeath, > enable VM_DEATH for env1,env2 > RequestedEvents: VMInit,VMDeath, > enable THREAD_END for env2 There must be something in the noncore library that registers callbacks in addition to what the test was expecting. But then I'm not sure why they wouldn't also be registered if the full non-partitioned libgcj was in use. Until I can figure this out, I guess I don't understand how dependencies work in java well enough, so patch withdrawn/on hold. cheers, DaveK ^ permalink raw reply [flat|nested] 6+ messages in thread
* [REVIVED: PATCH PR42811,4.5 regression] java.lang.ExceptionInInitializerError in ecj1 2010-02-06 6:12 ` Dave Korn @ 2010-02-15 2:49 ` Dave Korn 2010-02-15 13:04 ` Bryce McKinlay 0 siblings, 1 reply; 6+ messages in thread From: Dave Korn @ 2010-02-15 2:49 UTC (permalink / raw) To: Dave Korn; +Cc: Java Patches, GCC Patches [-- Attachment #1: Type: text/plain, Size: 1325 bytes --] On 06/02/2010 06:29, Dave Korn wrote: > On 05/02/2010 22:26, Dave Korn wrote: > >> libjava/ChangeLog: >> >> PR java/42811 >> * configure.ac (libgcj_spec_lgcj_override): Add undefined reference >> to arbitrary symbol in noncore library. >> (libgcj_spec_lgcj_bc_override): Likewise. >> >> I'm taking this for a bootstrap-and-test cycle on i686-pc-cygwin. Does it >> seem like a reasonable approach? > > It caused a regression: > >> FAIL: events output I've now tracked this regression down to a use of uninitialised memory in the core vm code(*), which appears to be entirely unrelated to (and presumably entirely accidentally exposed by) this patch. So, I'm reviving it. I'm running a full testsuite now for the combined patch, but I've already verified this regression no longer appears. libjava/ChangeLog: PR java/42811 * configure.ac (libgcj_spec_lgcj_override): Add undefined reference to arbitrary symbol in noncore library. (libgcj_spec_lgcj_bc_override): Likewise. configure: Regenerate. * jvmti.cc (_Jv_GetJVMTIEnv): Fix use of uninitialised memory exposed by the above change. Bootstrapped on i686-pc-cygwin; currently running check-target-libjava only. Assuming no regressions this time, OK for head? cheers, DaveK -- (*) - http://gcc.gnu.org/ml/java/2010-02/msg00002.html [-- Attachment #2: pr42811-take2.diff --] [-- Type: text/x-c, Size: 1607 bytes --] Index: libjava/configure.ac =================================================================== --- libjava/configure.ac (revision 156730) +++ libjava/configure.ac (working copy) @@ -244,9 +244,13 @@ if test "$enable_libgcj_sublibs" = yes ; then # tag "_bc" onto the end of it when we use it to generate the # spec, but that's an ugly thing to do when there are multiple # words in the string and you're relying on the ordering to - # append the correct one. - libgcj_spec_lgcj_override="-lgcj-noncore -lgcj" - libgcj_spec_lgcj_bc_override="-lgcj-noncore -lgcj_bc" + # append the correct one. Note that we add an arbitrary undef + # from libgcj-noncore to ensure the library is actually linked + # and loaded, as there aren't static dependencies to tell us + # which classes will be loaded at runtime, so we need to ensure + # that all the class data (.jcr sections) are present and initialised. + libgcj_spec_lgcj_override="-lgcj-noncore -u__ZN3org4ietf4jgss10GSSManagerC1Ev -lgcj" + libgcj_spec_lgcj_bc_override="-lgcj-noncore -u__ZN3org4ietf4jgss10GSSManagerC1Ev -lgcj_bc" fi Index: libjava/jvmti.cc =================================================================== --- libjava/jvmti.cc (revision 156730) +++ libjava/jvmti.cc (working copy) @@ -2210,6 +2210,7 @@ _Jv_GetJVMTIEnv (void) { _Jv_JVMTIEnv *env = (_Jv_JVMTIEnv *) _Jv_MallocUnchecked (sizeof (_Jv_JVMTIEnv)); + memset (env, 0, sizeof (_Jv_JVMTIEnv)); env->p = &_Jv_JVMTI_Interface; struct jvmti_env_list *element = (struct jvmti_env_list *) _Jv_MallocUnchecked (sizeof (struct jvmti_env_list)); ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [REVIVED: PATCH PR42811,4.5 regression] java.lang.ExceptionInInitializerError in ecj1 2010-02-15 2:49 ` [REVIVED: PATCH " Dave Korn @ 2010-02-15 13:04 ` Bryce McKinlay 2010-02-18 4:28 ` Dave Korn 0 siblings, 1 reply; 6+ messages in thread From: Bryce McKinlay @ 2010-02-15 13:04 UTC (permalink / raw) To: Dave Korn; +Cc: Java Patches, GCC Patches On Fri, Feb 5, 2010 at 10:26 PM, Dave Korn <dave.korn.cygwin@googlemail.com> wrote: > http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42811 > > > Hi lists, > > In this PR, ecj1 is failing (on Cygwin, presumably MinGW as well) owing to > unintended fallout from building libgcj as two separate DLLs. > > There are only static dependencies (i.e. unresolved symbols in the ecj.o > object) for ecjx to pull in the main libgcj at linktime, so only that DLL gets > loaded into memory at runtime. But the class loader wants to load something > from the subsidiary (-noncore) DLL, and it's not present in memory, so it > fails. (IIUC this is what the class definition data that is stored in .jcr > sections and made available to the class loader through a a .ctor-like > mechanism in the crtbegin code is all about.) > > In this patch, I add an arbitrary undef to the link spec, against a fairly > randomly chosen symbol (my only criterion was that the org.ietf.jgss namespace > is probably fairly stable) from the -noncore part of the library. This > sufficed to build an ecjx that links against and hence loads both DLLs, and it > doesn't throw the exception shown in the PR anymore. > libjava/ChangeLog: > > PR java/42811 > * configure.ac (libgcj_spec_lgcj_override): Add undefined reference > to arbitrary symbol in noncore library. Hi Dave I'm not sure if this sounds like the right fix. Isn't it the point of libgcj-noncore that applications which only want "core" classes can link a smaller libgcj without having to distribute or load the "noncore" classes? Doesn't adding a dependency from libgcj to libgcj-noncore defeat this? If ecj needs something from -noncore, shouldn't it be ecj that explicitly links it? > * jvmti.cc (_Jv_GetJVMTIEnv): Fix use of uninitialised memory > exposed by the above change. This part is fine. Bryce ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [REVIVED: PATCH PR42811,4.5 regression] java.lang.ExceptionInInitializerError in ecj1 2010-02-15 13:04 ` Bryce McKinlay @ 2010-02-18 4:28 ` Dave Korn 2010-02-18 15:38 ` Dave Korn 0 siblings, 1 reply; 6+ messages in thread From: Dave Korn @ 2010-02-18 4:28 UTC (permalink / raw) To: Bryce McKinlay; +Cc: Dave Korn, Java Patches, GCC Patches On 15/02/2010 13:04, Bryce McKinlay wrote: > On Fri, Feb 5, 2010 at 10:26 PM, Dave Korn wrote: >> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42811 >> In this PR, ecj1 is failing (on Cygwin, presumably MinGW as well) owing to >> unintended fallout from building libgcj as two separate DLLs. >> >> There are only static dependencies (i.e. unresolved symbols in the ecj.o >> object) for ecjx to pull in the main libgcj at linktime, so only that DLL gets >> loaded into memory at runtime. But the class loader wants to load something >> from the subsidiary (-noncore) DLL, and it's not present in memory, so it >> fails. (IIUC this is what the class definition data that is stored in .jcr >> sections and made available to the class loader through a a .ctor-like >> mechanism in the crtbegin code is all about.) >> >> In this patch, I add an arbitrary undef to the link spec, against a fairly >> randomly chosen symbol (my only criterion was that the org.ietf.jgss namespace >> is probably fairly stable) from the -noncore part of the library. This >> sufficed to build an ecjx that links against and hence loads both DLLs, and it >> doesn't throw the exception shown in the PR anymore. > >> libjava/ChangeLog: >> >> PR java/42811 >> * configure.ac (libgcj_spec_lgcj_override): Add undefined reference >> to arbitrary symbol in noncore library. > > Hi Dave Hi Bryce, thanks for getting back to me on this one. > I'm not sure if this sounds like the right fix. Isn't it the point of > libgcj-noncore that applications which only want "core" classes can > link a smaller libgcj without having to distribute or load the > "noncore" classes? Doesn't adding a dependency from libgcj to > libgcj-noncore defeat this? Yes, it does defeat that, but no, it's not the point. The real driving motivation behind breaking the library up into two parts is that it's simply too big and exceeds system limits when compiled as a monolithic shared library on some systems; specifically, it has ~82000 exported functions, and a windows DLL can export no more than 65535. It would certainly be a nice benefit if it was possible to load just one or the other individually, but it's only a nice-to-have; the subdivision itself is necessary simply for correctness on the affected targets. > If ecj needs something from -noncore, shouldn't it be ecj that > explicitly links it? Apologies in advance if I'm about to say something dumb, I'm no java specialist, but AIUI ecj (and other java apps) don't have to explicitly link against "things they need" in general, they call the class loader and it gets them either from a jar file on disk or by instantiating one of the built-in classes that were recorded in the .jcr section, right? Any app will assume that it can classload all of the standard library classes without having to do anything special, and I want it so that the subdivided library transparently behaves the same as the monoloithic one. So, nice though it might be, I just can't see any way of avoiding the necessity to load both libraries all the time everywhere (in order that all the .jcr sections get loaded and so all the expected classes are registered with the classloader), and that's what the effect of this patch should be. >> * jvmti.cc (_Jv_GetJVMTIEnv): Fix use of uninitialised memory >> exposed by the above change. > > This part is fine. Well: it appears to have caused a regression (investigating which is the reason why I took a while to respond to you). I'm now seeing: > Running /gnu/gcc/gcc/libjava/testsuite/libjava.loader/loader.exp ... > FAIL: /gnu/gcc/obj-pr42811-3/i686-pc-cygwin/libjava/testsuite/TestEarlyGC.exe output - /gnu/gcc/obj-pr42811-3/i686-pc-cygwin/libjava/testsuite/TestEarlyGC.exe *sigh*, and it turns out to be because some memory is getting released by the garbage collector when its still in use. I'm busy trying to learn how the GC works real fast so I can figure out what's going wrong. I was surprised to discover that the test executable links its own entirely separate copy of the GC library in addition to the one that's in the libjava DLL(s), is that supposed to happen? cheers, DaveK ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [REVIVED: PATCH PR42811,4.5 regression] java.lang.ExceptionInInitializerError in ecj1 2010-02-18 4:28 ` Dave Korn @ 2010-02-18 15:38 ` Dave Korn 0 siblings, 0 replies; 6+ messages in thread From: Dave Korn @ 2010-02-18 15:38 UTC (permalink / raw) To: Dave Korn; +Cc: Bryce McKinlay, Java Patches, GCC Patches On 18/02/2010 04:46, Dave Korn wrote: >>> * jvmti.cc (_Jv_GetJVMTIEnv): Fix use of uninitialised memory >>> exposed by the above change. >> This part is fine. > > Well: it appears to have caused a regression (investigating which is the > reason why I took a while to respond to you). I'm now seeing: > >> Running /gnu/gcc/gcc/libjava/testsuite/libjava.loader/loader.exp ... >> FAIL: /gnu/gcc/obj-pr42811-3/i686-pc-cygwin/libjava/testsuite/TestEarlyGC.exe output - /gnu/gcc/obj-pr42811-3/i686-pc-cygwin/libjava/testsuite/TestEarlyGC.exe > > *sigh*, and it turns out to be because some memory is getting released by the > garbage collector when its still in use. I'm busy trying to learn how the GC > works real fast so I can figure out what's going wrong. I'm now very sure that the problem is a side-effect of the libgcj DLL being rebased at runtime, and not related to the clearing of memory in _Jv_GetJVMTIEnv (which isn't even called in this testcase). So I'd like to go ahead with this part of the patch after all. I'll spend up to another 24 hours trying to fix the knock-on failure before I commit it, it would be nice to have the fix for that ready to go in at the same time. That still OK with you? (Also, did my explanation for the other part of the patch make sense, or do I need to go into more detail about anything?) > I was surprised to > discover that the test executable links its own entirely separate copy of the > GC library in addition to the one that's in the libjava DLL(s), is that > supposed to happen? I was wrong about this, it was a red herring caused by the fact that libgcj was getting rebased down to a runtime address so low that I thought it was in the EXE's text section; in fact it was not. I've now proven that by rebasing all the other DLLs out of the way I can make the test pass or fail just by moving around where libgcj gets loaded in the process memory space, and it fails in different ways according to where I move it to, which is symptomatic of a problem with base relocations in the generated DLL. I'm going to look at how the GC determines the extent of the DLL's data area when it looks for pointers during the mark phase, because if the static data region ranges aren't being fixed up correctly when the DLL gets rebased to a different load address at runtime, that could cause this kind of problem. cheers, DaveK ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2010-02-18 15:38 UTC | newest] Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2010-02-05 22:09 [PATCH PR42811,4.5 regression] java.lang.ExceptionInInitializerError in ecj1 Dave Korn 2010-02-06 6:12 ` Dave Korn 2010-02-15 2:49 ` [REVIVED: PATCH " Dave Korn 2010-02-15 13:04 ` Bryce McKinlay 2010-02-18 4:28 ` Dave Korn 2010-02-18 15:38 ` Dave Korn
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).