Good.

Just a small spelling error “Espected” -> “Expected”.

/Staffan

On 14 feb 2014, at 11:00, shanliang <shanliang.ji...@oracle.com> wrote:

> Staffan Larsen wrote:
>> 
>> This version looks good! Thanks for hanging in there.
>> 
>> The only improvement would be to count and verify the number of 
>> ModificationWatchpointEvent (there should be 10).
> Good idea, here is:
> http://cr.openjdk.java.net/~sjiang/JDK-8007710/05/
> 
> Thanks,
> Shanliang
>> 
>> Thanks,
>> /Staffan
>> 
>> On 13 feb 2014, at 21:15, shanliang <shanliang.ji...@oracle.com> wrote:
>> 
>>> Hi,
>>> 
>>> Here is Version 4:
>>>     http://cr.openjdk.java.net/~sjiang/JDK-8007710/04/
>>> 
>>> 1) remove the line
>>>     108   vm.resume()
>>> 2) call addClassWatch(vm) only when receiving VMStartEvent
>>> 3) make sure that the test receives ModificationWatchpointEvent
>>> 4) clean
>>> 
>>> Thanks,
>>> Shanliang
>>> 
>>> shanliang wrote:
>>>> 
>>>> Staffan,
>>>> 
>>>> Very nice analysis! 
>>>> 
>>>> The fix must be very simple, just remove the line 
>>>>     108   vm.resume
>>>> it is an error because here the test does not yet treat the events in 
>>>> eventSet.
>>>> 
>>>> the line
>>>>     136   eventSet.resume();
>>>> is the right place to resume the threads after event treatment.
>>>> 
>>>> Here is the new webrev:
>>>> http://cr.openjdk.java.net/~sjiang/JDK-8007710/03/
>>>> 
>>>> Thanks,
>>>> Shanliang
>>>> 
>>>> Staffan Larsen wrote:
>>>>> 
>>>>> I think I understand what happens now.
>>>>> 
>>>>> The test code, simplified, looks like this (with the Thread.sleep() added 
>>>>> that causes the test to fail):
>>>>> 
>>>>>   launchTarget();
>>>>>   addClassWatch();
>>>>>   vm.resume();
>>>>>   Thread.sleep(1000);
>>>>>   while(connected) {
>>>>>       eventSet = eventQueue.remove()
>>>>>       for(event : eventQueue) {
>>>>>           if (event instanceof ClassPrepareEvent) {
>>>>>               addFieldWatch();
>>>>>           }
>>>>>       }
>>>>>       eventSet.resume();
>>>>>   }
>>>>> 
>>>>> By default all events that happen will cause the debuggee to suspend (see 
>>>>> EventRequest.setSuspendPolicy()). Thus when we get to addFieldWatch(), 
>>>>> the vm should be suspended and we should be able to create the field 
>>>>> watch without problem. But the VM isn’t suspended and that is why the 
>>>>> test fail. 
>>>>> 
>>>>> Why isn’t the VM suspended? When we get to the “for(event : eventQueue)” 
>>>>> the first time there are *two* events already in the queue: the 
>>>>> VMStartEvent and a ClassPrepareEvent. At this point the VM is suspended 
>>>>> and everything is good. We look at the first eventSet which only contains 
>>>>> the VMStartEvent, we ignore the event, but we resume the VM. We then loop 
>>>>> and look at the ClassPrepareEvent, but by now the VM is already running 
>>>>> and has also terminated. Failure.
>>>>> 
>>>>> Thus, we need to handle the VMStartEvent. I suggest a modification to my 
>>>>> previous code:
>>>>> 
>>>>>   launchTarget();
>>>>>   while(connected) {
>>>>>       eventSet = eventQueue.remove()
>>>>>       for(event : eventQueue) {
>>>>>           if (event instanceof VMStartEvent) {
>>>>>               addClassWatch();
>>>>>           }
>>>>>           if (event instanceof ClassPrepareEvent) {
>>>>>               addFieldWatch();
>>>>>           }
>>>>>       }
>>>>>       eventSet.resume();
>>>>>   }
>>>>> 
>>>>> This will cause us to have complete control over the state of the 
>>>>> debuggee. The first event we see will be the VMStartEvent. The VM will be 
>>>>> suspended. We can add a class watch here. Then we resume the VM. The 
>>>>> second event we see will be the ClassPrepareEvent with the VM suspended. 
>>>>> We can add the field watch. Then we resume the VM and wait for the field 
>>>>> watch events.
>>>>> 
>>>>> Thanks,
>>>>> /Staffan
>>>>> 
>>>>> On 13 feb 2014, at 11:36, shanliang <shanliang.ji...@oracle.com> wrote:
>>>>> 
>>>>>> Staffan Larsen wrote:
>>>>>>> 
>>>>>>> On 13 feb 2014, at 10:17, Jaroslav Bachorik 
>>>>>>> <jaroslav.bacho...@oracle.com> wrote:
>>>>>>> 
>>>>>>>   
>>>>>>>> Hi Staffan,
>>>>>>>> 
>>>>>>>> On 12.2.2014 18:27, Staffan Larsen wrote:
>>>>>>>>     
>>>>>>>>> I’m still not happy with this fix since I think the extra output 
>>>>>>>>> stream synchronization logic is not needed - the debuggee should be 
>>>>>>>>> suspended at all the interesting points. The fix I proposed is 
>>>>>>>>> cleaner and (as far as I can tell) also fixes the problem. The only 
>>>>>>>>> thing is that I can’t quite explain what goes wrong without the fix… 
>>>>>>>>> I’d really like to understand that. I’ll try to dig deeper and see if 
>>>>>>>>> I can understand exactly what happens.
>>>>>>>>>       
>>>>>>>> Yes, bringing the VM to a stable state before calling other JDI 
>>>>>>>> functions helps to stabilize the test even without the additional 
>>>>>>>> synchronization via stdout/stdin.
>>>>>>>> 
>>>>>>>> I just wonder whether this check should not be done inside 
>>>>>>>> com.sun.jdi.connect.LaunchingConnector#launch() implementation. Does 
>>>>>>>> it even make sense to hand off an unstable VM?
>>>>>>>>     
>>>>>>> Good question, but hard to change now - all implementations depend on 
>>>>>>> the current functionality. The VMStartEvent also gives you a reference 
>>>>>>> to the main thread.
>>>>>>>   
>>>>>> The test failed when it received ClassPrepareEvent and did 
>>>>>> addFieldWatch, that meant the test must receive already VMStartEvent, 
>>>>>> because VMStartEvent must be the first event, if it was true then the vm 
>>>>>> must be already stable when failing.
>>>>>> 
>>>>>> Except that the test received ClassPrepareEvent before VMStartEvent then 
>>>>>> it was doing addFieldWatch with a possibly unstable VM. in this case we 
>>>>>> might have a serious bug in VirtualMachine implementation, and if this 
>>>>>> is true the fix proposed to check "start" may make miss 
>>>>>> ClassPrepareEvent, then the test would test nothing.
>>>>>> 
>>>>>> Shanliang
>>>>>>> /S
>>>>>>> 
>>>>>>>   
>>>>>>>> -JB-
>>>>>>>> 
>>>>>>>>     
>>>>>>>>> /Staffan
>>>>>>>>> 
>>>>>>>>> On 12 feb 2014, at 18:04, shanliang <shanliang.ji...@oracle.com> 
>>>>>>>>> wrote:
>>>>>>>>> 
>>>>>>>>>       
>>>>>>>>>> Staffan Larsen wrote:
>>>>>>>>>>         
>>>>>>>>>>> I think what you need to do is wait for the VMStartEvent before you 
>>>>>>>>>>> add requests to the VM. Note this paragraph from the VirtualMachine 
>>>>>>>>>>> doc:
>>>>>>>>>>> 
>>>>>>>>>>>  Note that a target VM launched by a launching connector is not
>>>>>>>>>>>  guaranteed to be stable until after the VMStartEvent has been
>>>>>>>>>>>  received.
>>>>>>>>>>> 
>>>>>>>>>>>           
>>>>>>>>>> I may miss something here, I believe VMStartEvent must be the first 
>>>>>>>>>> event, when the test got ClassPrepareEvent, it must already received 
>>>>>>>>>> VMStartEvent.
>>>>>>>>>>         
>>>>>>>>>>> I think adding code that looks something like this will make the 
>>>>>>>>>>> test stable:
>>>>>>>>>>> 
>>>>>>>>>>>     VirtualMachine vm = launchTarget(CLASS_NAME);
>>>>>>>>>>>     EventQueue eventQueue = vm.eventQueue();
>>>>>>>>>>> 
>>>>>>>>>>>     boolean started = false;
>>>>>>>>>>>     while(!started) {
>>>>>>>>>>>       EventSet eventSet = eventQueue.remove();
>>>>>>>>>>>       for (Event event : eventSet) {
>>>>>>>>>>>         if (event instanceof VMStartEvent) {
>>>>>>>>>>>           started = true;
>>>>>>>>>>>         }
>>>>>>>>>>>         if (event instanceof VMDeathEvent
>>>>>>>>>>>             || event instanceof VMDisconnectEvent) {
>>>>>>>>>>>           throw new Error("VM died before it started...:"+event);
>>>>>>>>>>>         }
>>>>>>>>>>>       }
>>>>>>>>>>>     }
>>>>>>>>>>> 
>>>>>>>>>>>     System.out.println("Vm launched");
>>>>>>>>>>> 
>>>>>>>>>>>           
>>>>>>>>>> The code you proposed could improve the test, it made sure that 
>>>>>>>>>> TestPostFieldModification was started, but I am afraid that it did 
>>>>>>>>>> not address the issue causing the failure, the issue I believe was 
>>>>>>>>>> that TestPostFieldModification exited before or during FieldMonitor 
>>>>>>>>>> called addFieldWatch(), that was why addFieldWatch() received 
>>>>>>>>>> VMDisconnectedException. When the test was treating 
>>>>>>>>>> ClassPrepareEvent, even if VMDeathEvent or VMDisconnectEvent 
>>>>>>>>>> arrived, it must be still waiting in the eventQueue because it 
>>>>>>>>>> arrived after ClassPrepareEvent.
>>>>>>>>>> 
>>>>>>>>>> My fix was to not allow TestPostFieldModification to exit before 
>>>>>>>>>> addFieldWatch() was done.
>>>>>>>>>>         
>>>>>>>>>>> There is also no reason to call addFieldWatch() before the 
>>>>>>>>>>> ClassPrepareEvent has been received. The call to 
>>>>>>>>>>> vm..classesByName() will just return an empty list anyway.
>>>>>>>>>>> 
>>>>>>>>>>>           
>>>>>>>>>> I do not know why the test called addFieldWatch before 
>>>>>>>>>> ClassPrepareEvent had been received, but yes the returned list was 
>>>>>>>>>> empty, so agree to remove it.
>>>>>>>>>>         
>>>>>>>>>>> While you are in there you can also remove the unused StringBuffer 
>>>>>>>>>>> near the top of main().
>>>>>>>>>>> 
>>>>>>>>>>>           
>>>>>>>>>> Yes it was already removed in version 01
>>>>>>>>>> 
>>>>>>>>>> Here is the new webrev:
>>>>>>>>>> http://cr.openjdk.java.net/~sjiang/JDK-8007710/02/
>>>>>>>>>> 
>>>>>>>>>> Thanks,
>>>>>>>>>> Shanliang
>>>>>>>>>>         
>>>>>>>>>>> Thanks,
>>>>>>>>>>> /Staffan
>>>>>>>>>>> 
>>>>>>>>>>> On 11 feb 2014, at 18:30, shanliang <shanliang.ji...@oracle.com> 
>>>>>>>>>>> wrote:
>>>>>>>>>>> 
>>>>>>>>>>> 
>>>>>>>>>>>           
>>>>>>>>>>>> Here is the new fix in which FieldMonitor will write to 
>>>>>>>>>>>> TestPostFieldModification, to inform the latter to quit, as 
>>>>>>>>>>>> suggested bu Jaroslav
>>>>>>>>>>>>   http://cr.openjdk.java.net/~sjiang/JDK-8007710/01/
>>>>>>>>>>>> 
>>>>>>>>>>>> Thanks,
>>>>>>>>>>>> Shanliang
>>>>>>>>>>>> 
>>>>>>>>>>>> shanliang wrote:
>>>>>>>>>>>> 
>>>>>>>>>>>>             
>>>>>>>>>>>>> shanliang wrote:
>>>>>>>>>>>>> 
>>>>>>>>>>>>>               
>>>>>>>>>>>>>> Jaroslav Bachorik wrote:
>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>                 
>>>>>>>>>>>>>>> On 11.2.2014 16:31, shanliang wrote:
>>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>>                   
>>>>>>>>>>>>>>>> Staffan Larsen wrote:
>>>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>>>                     
>>>>>>>>>>>>>>>>> Hi Shanliang,
>>>>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>>>> I can’t quite see how the test can fail in this way. When the
>>>>>>>>>>>>>>>>> ClassPrepareEvent happens, the debuggee will be suspended. So 
>>>>>>>>>>>>>>>>> when
>>>>>>>>>>>>>>>>> addFieldWatch() is called, the debuggee should not have moved.
>>>>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>>>>                       
>>>>>>>>>>>>>>>> I am not expert of jdi so I may miss something here. I checked 
>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>> failure trace and saw the report exception happen when 
>>>>>>>>>>>>>>>> FieldMonitor
>>>>>>>>>>>>>>>> received ClassPrepareEvent and was doing addFieldWatch. 
>>>>>>>>>>>>>>>> FieldMonitor did
>>>>>>>>>>>>>>>> call "vm.resume()" before treating events.
>>>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>>>                     
>>>>>>>>>>>>>>> AFAICS, calling vm.resume() results in an almost immediate 
>>>>>>>>>>>>>>> debuggee death. The gc() invoking thread "d" is flagged as a 
>>>>>>>>>>>>>>> deamon and as such doesn't prevent the process from exiting. 
>>>>>>>>>>>>>>> The other thread is not a daemon but will finish in only few 
>>>>>>>>>>>>>>> cycles.
>>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>>                   
>>>>>>>>>>>>>> I looked at the class com.sun.jdi.VirtualMachine, here is the 
>>>>>>>>>>>>>> Javadoc of the method "resume":
>>>>>>>>>>>>>>   /**
>>>>>>>>>>>>>>    * Continues the execution of the application running in this
>>>>>>>>>>>>>>    * virtual machine. All threads are resumed as documented in
>>>>>>>>>>>>>>    * {@link ThreadReference#resume}.
>>>>>>>>>>>>>>    *
>>>>>>>>>>>>>>    * @throws VMCannotBeModifiedException if the VirtualMachine 
>>>>>>>>>>>>>> is read-only - see {@link VirtualMachine#canBeModified()}.
>>>>>>>>>>>>>>    *
>>>>>>>>>>>>>>    * @see #suspend
>>>>>>>>>>>>>>    */
>>>>>>>>>>>>>>   void resume();
>>>>>>>>>>>>>> My understanding is that the debuggee resumes to work after this 
>>>>>>>>>>>>>> call, instead to die?
>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>                 
>>>>>>>>>>>>> In fact the problem is here, the vm (TestPostFieldModification) 
>>>>>>>>>>>>> should not die before FieldMonitor finishes addFieldWatch.
>>>>>>>>>>>>> 
>>>>>>>>>>>>> Shanliang
>>>>>>>>>>>>> 
>>>>>>>>>>>>>               
>>>>>>>>>>>>>>>> I reproduced the bug by add sleep(1000) after vm.resume() but 
>>>>>>>>>>>>>>>> before
>>>>>>>>>>>>>>>> calling eventQueue.remove();
>>>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>>>                     
>>>>>>>>>>>>>>> It looks like some kind of synchronization between the debugger 
>>>>>>>>>>>>>>> and the debuggee is necessary. But I wonder if you should 
>>>>>>>>>>>>>>> better use the process.getOuptuptStream() to write and flush a 
>>>>>>>>>>>>>>> message for the debugee indicating that it can exit. And in the 
>>>>>>>>>>>>>>> debugee you would just do System.in.read() as the last 
>>>>>>>>>>>>>>> statement in the main() method. Seems more robust than 
>>>>>>>>>>>>>>> involving files.
>>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>>                   
>>>>>>>>>>>>>> It could work, but creating a file in the testing directory 
>>>>>>>>>>>>>> should have no issue, but yes maybe less performance.
>>>>>>>>>>>>>> 
>>>>>>>>>>>>>> Thanks,
>>>>>>>>>>>>>> Shanliang
>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>                 
>>>>>>>>>>>>>>> Cheers,
>>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>> -JB-
>>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>>                   
>>>>>>>>>>>>>>>> Thanks,
>>>>>>>>>>>>>>>> Shanliang
>>>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>>>                     
>>>>>>>>>>>>>>>>> One problem I do see with the test is that it does not wait 
>>>>>>>>>>>>>>>>> for a
>>>>>>>>>>>>>>>>> VMStartEvent before setting up requests. I’m not sure if that 
>>>>>>>>>>>>>>>>> could
>>>>>>>>>>>>>>>>> cause the failure in the bug report, though.
>>>>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>>>> /Staffan
>>>>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>>>> On 11 feb 2014, at 15:13, shanliang 
>>>>>>>>>>>>>>>>> <shanliang.ji...@oracle.com> wrote:
>>>>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>>>>                       
>>>>>>>>>>>>>>>>>> Hi ,
>>>>>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>>>>> The problem could be that FieldMonitor did not have enough 
>>>>>>>>>>>>>>>>>> time to
>>>>>>>>>>>>>>>>>> "addFieldWatch" but the vm to monitor 
>>>>>>>>>>>>>>>>>> (TestPostFieldModification) was
>>>>>>>>>>>>>>>>>> already ended.
>>>>>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>>>>> So we should make sure that TestPostFieldModification exits 
>>>>>>>>>>>>>>>>>> after
>>>>>>>>>>>>>>>>>> FieldMonitor has done necessary. The solution proposed here 
>>>>>>>>>>>>>>>>>> is that
>>>>>>>>>>>>>>>>>> FieldMonitor creates a file after adding field watching, and
>>>>>>>>>>>>>>>>>> TestPostFieldModification quits only after finding the file.
>>>>>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>>>>> web:
>>>>>>>>>>>>>>>>>> http://icncweb.fr.oracle.com/~shjiang/webrev/8007710/00/
>>>>>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>>>>> bug:
>>>>>>>>>>>>>>>>>> https://bugs.openjdk.java.net/browse/JDK-8007710
>>>>>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>>>>> Thanks,
>>>>>>>>>>>>>>>>>> Shanliang
>>>>>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>>>>>                         
>>>>>>>>>>         
>>>>>>>>>       
>>>>>>>   
>>>>>> 
>>>>>> 
>>>>> 
>>>> 
>>> 
>> 
> 

Reply via email to