JVM crashes when adding more than 2 methods to java.lang.Object
tom.rodriguez at oracle.com
Wed Apr 28 23:11:01 PDT 2010
Just adding a flag seems hacky though I'm not sure how easy it is to fix this without some ugliness.
Universe::base_vtable_size gets the hard wired constant vtable size but the right way to set this would be to parse Object before creating any of the primitive array types which isn't really feasible I think. Look at the logic in Universe::genesis which is where it begins creating type array classes. A little further along it calls SystemDictionary::initialize which starts loading and parsing the classes. The last step is calling in universe_post_init where it fills into the vtables after bootstrap which is where it dies in product mode.
I just noticed the fixup_mirrors stage that deals with ordering problems with Class and I think it could this could handle in there by essentially redefining any classes which were created before we knew the actual size of Object. We'd then go through perm and replace the old klass pointer with the new klass pointer. So the parsing of Object would correct the value of base_vtable_size and maybe set a flag indicating that we need to recreate the array classes. Then during fixup mirrors we'd rewrite the keap to point at the new ones. Anyway, I think something like that would work. Maybe. :)
On Apr 28, 2010, at 8:21 PM, Guillaume Pothier wrote:
> Thanks for the explanation Tom. Would a patch that adds a -X or -XX
> JVM parameter to specify the size of the Object/arrays vtable be
> welcome? Or is it too specific/hacky to be included? What source file
> would be a good starting point to look at the issue?
> On Wed, Apr 28, 2010 at 5:40 PM, Tom Rodriguez <tom.rodriguez at oracle.com> wrote:
>> On Apr 28, 2010, at 12:12 PM, Guillaume Pothier wrote:
>>> Thanks a lot for your reply. I forgot to mention that I'm adding the
>>> methods either through instrumentation using a native JVMTI agent, or
>>> by providing the modified Object class file using the
>>> -Xbootclasspath/p command line option (both techniques yielding the
>>> same results). Wouldn't that count as occurring before JVM bootstrap?
>> Xbootclasspath/p certainly is early enough but I'd forgotten about the improvement in JVMTI that allowed agents to be inited before any classes have been loaded, so it should also be early enough. This actually make more sense to me since I would have expected JVMTI to reject any attempt to retransform a class to add public methods.
>> Looking more closely at bootstrap it appears that Object starts off with a fixed size vtable and it will die if you define extra virtuals in Object. It appears to be done this way because the klasses for primitive array types are created before we've actually parsed Object so we don't know how many virtuals there really are. So Object actually gets its vtable constructed properly but the array klasses are too small so you die. I think the reason it has to be done this way is that we use Java primitive arrays in a few cases to hold class meta data so they need it exist before we start parsing and building classes.
>> Anyway, so it looks like you can't add virtuals in object but you can safely add public final ones if that helps. The JVM should fail more gracefully than this in product mode but all the code that checks this is asserts so it disappears. It seems like the restriction could be remove if we wanted to as well.
>>> I'll ask on serviceability-dev, but in the mean time any insight would
>>> be appreciated.
>>> On Wed, Apr 28, 2010 at 2:09 PM, Tom Rodriguez <tom.rodriguez at oracle.com> wrote:
>>>> I didn't think we supporting redefining Object and adding public methods after JVM bootstrap. Adding methods to classes which are already loaded with subclasses means that you have to generate new vtables for all subclasses and as far as I know we don't do that. You might get more answer over on serviceability-dev.
>>>> On Apr 24, 2010, at 1:30 PM, Guillaume Pothier wrote:
>>>>> First of all I hope it is appropriate to ask this kind of question in
>>>>> this list, otherwise what would be the correct forum?
>>>>> Here is my problem: I'm adding public, non-native methods to the
>>>>> Object class through instrumentation, and it seems that adding more
>>>>> than 2 such methods causes the JVM to crash. I get different kinds of
>>>>> crashes depending on the number of methods I add. With 3 and 4 methods
>>>>> I get a SIGSEGV; with more methods I get an NPE during VM
>>>>> initialization (in String.charAt). For testing purposes, all added
>>>>> methods take no arguments and return void, and have an empty body
>>>>> (only the RETURN bytecode).
>>>>> Is that expected behavior? Is there something I can do about it?
>>>>> Kind regards,
>>>>> Guillaume Pothier
>>>>> PhD student, University of Chile
More information about the hotspot-dev