RFR (M): 8026328: Setting a breakpoint on invokedynamic crashes the JVM

serguei.spitsyn at oracle.com serguei.spitsyn at oracle.com
Thu Oct 24 16:14:18 PDT 2013


On 10/24/13 4:12 PM, serguei.spitsyn at oracle.com wrote:
> On 10/24/13 3:45 PM, Christian Thalinger wrote:
>>
>> On Oct 24, 2013, at 3:02 PM, Christian Thalinger 
>> <christian.thalinger at oracle.com 
>> <mailto:christian.thalinger at oracle.com>> wrote:
>>
>>>
>>> On Oct 23, 2013, at 3:46 PM,serguei.spitsyn at oracle.com 
>>> <mailto:serguei.spitsyn at oracle.com>wrote:
>>>
>>>> Chris,
>>>>
>>>> This fix is nice, thank you for doing it!
>>>> I don't see any issues except this one:
>>>>
>>>>   566 /**
>>>>   567  * Returns the return entry address for the given top-of-stack state and bytecode.
>>>>   568  */
>>>>   569 address TemplateInterpreter::return_entry(TosState state, int length, Bytecodes::Code code) {
>>>>   570   guarantee(0 <= length && length < Interpreter::number_of_return_entries, "illegal length");
>>>>   571   const int index = TosState_as_index(state);
>>>>   572   switch (code) {
>>>>   573   case Bytecodes::_invokestatic:
>>>>   574   case Bytecodes::_invokespecial:
>>>>   575   case Bytecodes::_invokevirtual:
>>>>   576     return _invoke_return_entry[index];
>>>>   577   case Bytecodes::_invokeinterface:
>>>>   578     return _invokeinterface_return_entry[index];
>>>>   579   case Bytecodes::_invokedynamic:
>>>>   580     return _invokedynamic_return_entry[index];
>>>>   581   default:
>>>>   582     return _return_entry[length].entry(state);
>>>>   583   }
>>>>   584 }
>>>> Should the above switch also include the _invokehandle case?
>>>
>>> Good point.  It should.  I’ve also added an assert to make sure we 
>>> don’t end up with an invoke instruction in the default case:
>>>
>>> +  default:
>>> + assert(!Bytecodes::is_invoke(code), err_msg("invoke instructions 
>>> should be handled separately: %s", Bytecodes::name(code)));
>>> +    return _return_entry[length].entry(state);
>>
>> Which brings up another question:  should Bytecodes::is_invoke 
>> include a check for invokehandle?  I think it should but we shouldn’t 
>> make that change so late in the 8 game.
>
> I do not see the Bytecodes::is_invoke is used widely.
>
> It is used in 4 other asserts:
>
> ops/methodData.cpp: assert(Bytecodes::is_invoke(stream->code()), 
> "should be invoke");
> oops/methodData.cpp: assert(Bytecodes::is_invoke(stream->code()), 
> "should be invoke");
> oops/methodData.cpp: assert(Bytecodes::is_invoke(stream->code()), 
> "should be invoke");
>
> interpreter/bytecodes.hpp:  static bool        has_receiver (Code 
> code)    { assert(is_invoke(code), "");  return code == _invokevirtual ||
>
>
> Fixing it in Bytecodes::is_invoke looks pretty so far but depends on 
> the usage in methodData.cpp.

Correction: "looks pretty safe so far".  :)

Thanks,
Serguei

>
>
> Thanks,
> Serguei
>
>>
>>>
>>>>
>>>>
>>>> How did you test it?
>>>> It is necessary to run the nsk.jvmti and nsk.jdi testlists.
>>>
>>> It tested various things manually and did a JPRT run.  Since I 
>>> touched every invoke return entry in the system running some random 
>>> code automatically tests this code.
>>>
>>>>
>>>> Thanks,
>>>> Serguei
>>>>
>>>>
>>>> On 10/23/13 11:06 AM, Christian Thalinger wrote:
>>>>> https://bugs.openjdk.java.net/browse/JDK-8026328
>>>>> http://cr.openjdk.java.net/~twisti/8026328/webrev.00/
>>>>>
>>>>> 8026328: Setting a breakpoint on invokedynamic crashes the JVM
>>>>> Reviewed-by:
>>>>>
>>>>> Well-known invoke instructions have a 2-byte index but invokedynamic has a 4-byte index. In return entries we check the bytecode instruction to decide which size the index has.
>>>>>
>>>>> The problem is that if there is a breakpoint there is no way to know what index size the instruction has because the original instruction byte was replaced with the breakpoint byte.
>>>>>
>>>>> There are a couple of ways to fix this but the proper way (in my opinion) is to have separate return entries for the different classes of invoke instructions.  This on one hand generates more return entries but on the other hand makes them smaller and simpler.
>>>>>
>>>
>>
>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.openjdk.java.net/pipermail/hotspot-compiler-dev/attachments/20131024/e4ca1cbc/attachment.html 


More information about the hotspot-compiler-dev mailing list