-
Bug
-
Resolution: Duplicate
-
P4
-
None
-
1.4.0
-
generic
-
generic
Name: abR10010 Date: 12/05/2001
The part of the specification for the interface EventRequest
related to filters, states the following:
The number of events generated for an event request can be controlled through filters.
Filters provide additional constraints that an event must satisfy
before it is placed on the event queue.
Multiple filters can be used by making multiple calls to filter addition methods
such as ExceptionRequest.addClassFilter(java.lang.String classPattern).
Filters are added to an event one at a time only while the event is disabled.
Multiple filters are applied with CUT-OFF AND,
in the order it was added to the request.
Only events that satisfy all filters are placed in the event queue.
The specification for the method
EventRequestManager.createStepRequest(ThreadReference, int, int)
contains the following clause:
The returned request will control stepping only in the specified thread;
all other threads will be unaffected.
However, a test against the method StepRequest.addClassFilter(ReferenceType refType)
shows that if
- two StepRequsts are created in two different threads in a debuggee,
thread1 and thread2;
- to first StepRequest, the method is applied two times,
both with the same ReferenceType object as arguments,
hence, a corresponding event, event1, should be received;
- to second StepRequest, the method is also applied two times,
but with different ReferenceType objects as arguments,
hence, a corresponding event, event2, should not be received;
- the method EventRequest.enabled() is applied to both requests;
!!! - the thread1 dies first;
the event1 is NOT received too.
Hence, there is no complience with the above statement:
The returned request will control stepping only in the specified thread;
all other threads will be unaffected.
Note.
If the test gets a modification resulting in the thread2 dies first,
the event1 is received.
This unspecified result is observed
when HS 1.4.0-rc-b88 is runnning a test program
on the following H/S configurations:
- SUNW Ultra1: sparc 200MHz, RAM 128Mb;
OS: Solaris-8;
JVM: Client & Server
- Intel: 2-processor i686 600MHz processor, RAM 512Mb;
OS: Solaris-8;
JVM: Client & Server
- Intel: 2-processor i686 600MHz processor, RAM 512Mb;
OS: Linux/RedHat6.2;
JVM: Client & Server
- Intel: Pentium-II 350MHz, RAM 128Mb;
OS: WinNT/4-Workstation;
JVM: Client & Server
Corresponding code fragments in a debugger and a debuggee and two logs,
for the cases with two and one enabled request accordingly,
are below.
Steps to reproduce the bug:
1. cd /net/sqesvr.sfbay/export/vsn/GammaBase/Bugs/{this bug ID}
2. sh doit1.sh {JAVA_HOME}
To reproduce the case without the error, the step 2 is:
2. sh doit2.sh {JAVA_HOME}
This bug affects the following testbase_nsk tests:
nsk/jdi/StepRequest/addClassFilter_rt/filter_rt003
The tests will be in the next release of testbase_nsk;
the current release of testbase_nsk (1.4) is accessible through:
/net/sqesvr.sfbay/export/vsn/VM/testbase/testbase_nsk.v14
///////////////////////////////////////////////////////////////////////
///////////// code fragments in the debugger: filter_rt003.java
private String debuggeeName =
"nsk.jdi.StepRequest.addClassFilter_rt.filter_rt003a";
private String testedClassName10 =
"nsk.jdi.StepRequest.addClassFilter_rt.TestClass10";
private String testedClassName20 =
"nsk.jdi.StepRequest.addClassFilter_rt.TestClass20";
//////
log1(" TESTING BEGINS");
EventRequest eventRequest1 = null;
EventRequest eventRequest2 = null;
String property1 = "StepRequest1";
String property2 = "StepRequest2";
ReferenceType testClassReference10 = null;
ReferenceType testClassReference20 = null;
ThreadReference thread1 = null;
String threadName1 = "thread1";
ThreadReference thread2 = null;
String threadName2 = "thread2";
int errorFlag = 0;
vm.resume(); // !!
for (int i = 0; ; i++) {
if (errorFlag == 0)
breakpointForCommunication();
int instruction = ((IntegerValue)
(debuggeeClass.getValue(debuggeeClass.fieldByName("instruction")))).value();
if (instruction == 0) {
vm.resume();
break;
}
log1(":::::: case: # " + i);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ variable part
switch (i) {
case 0:
testClassReference10 =
(ReferenceType) vm.classesByName(testedClassName10).get(0);
testClassReference20 =
(ReferenceType) vm.classesByName(testedClassName20).get(0);
thread1 = threadByName(threadName1);
thread2 = threadByName(threadName2);
eventRequest1 = setting21StepRequest(thread1, testClassReference10,
EventRequest.SUSPEND_NONE, property1);
eventRequest2 = setting21StepRequest(thread2, testClassReference10,
EventRequest.SUSPEND_NONE, property2);
((StepRequest) eventRequest1).addClassFilter(testClassReference10);
((StepRequest) eventRequest2).addClassFilter(testClassReference20);
eventRequest1.enable();
eventRequest2.enable();
mainThread.resume();
log2("......waiting for StepEvent in expected thread");
getEventSet();
Event newEvent = eventIterator.nextEvent();
if ( !(newEvent instanceof StepEvent)) {
log3("ERROR: new event is not StepEvent");
testExitCode = FAILED;
if (newEvent instanceof BreakpointEvent) {
log3("ERROR: new event is BreakpointEvent");
errorFlag = 1;
break;
}
} else {
String property = (String) newEvent.request().getProperty("number");
log2(" got new StepEvent with propety 'number' == " + property);
if ( !property.equals(property1) ) {
log3("ERROR: property is not : " + property1);
testExitCode = FAILED;
}
if (eventSet.size() != 1) {
log3("ERROR: eventSet.size() != 1 : " + eventSet.size());
testExitCode = FAILED;
}
}
break;
default:
throw new JDITestRuntimeException("** default case 2 **");
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
}
log1(" TESTING ENDS");
///////////// code fragments in the debuggee
static Thread1filter_rt003a thread1 = null;
static Thread2filter_rt003a thread2 = null;
static TestClass10 obj10 = new TestClass10();
static TestClass20 obj20 = new TestClass20();
//------------------------------------------------------ common section
static int exitCode = PASSED;
static int instruction = 1;
static int end = 0;
// static int quit = 0;
// static int continue = 2;
static int maxInstr = 1; // 2;
static int lineForComm = 2;
private static void methodForCommunication() {
int i1 = instruction;
int i2 = i1;
int i3 = i2;
}
//---------------------------------------------------- main method
public static void main (String argv[]) {
argHandler = new ArgumentHandler(argv);
log = argHandler.createDebugeeLog();
log1("debuggee started!");
for (int i = 0; ; i++) {
if (instruction > maxInstr) {
logErr("ERROR: unexpected instruction: " + instruction);
exitCode = FAILED;
break ;
}
switch (i) {
//------------------------------------------------------ section tested
case 0:
thread1 = new Thread1filter_rt003a("thread1");
thread2 = new Thread2filter_rt003a("thread2");
synchronized (lockObj2) {
synchronized (lockObj1) {
threadStart(thread1);
threadStart(thread2);
log1("methodForCommunication();----1");
methodForCommunication();
}
try {
thread1.join();
} catch ( InterruptedException e ) {
}
}
try {
thread2.join();
} catch ( InterruptedException e ) {
}
//------------------------------------------------- standard end section
default:
instruction = end;
break;
}
log1("methodForCommunication();");
methodForCommunication();
if (instruction == end)
break;
}
log1("debuggee exits");
System.exit(exitCode + PASS_BASE);
}
static Object lockObj1 = new Object();
static Object lockObj2 = new Object();
static Object waitnotifyObj = new Object();
static int threadStart(Thread t) {
synchronized (waitnotifyObj) {
t.start();
try {
waitnotifyObj.wait();
} catch ( Exception e) {
exitCode = FAILED;
logErr(" Exception : " + e );
return FAILED;
}
}
return PASSED;
}
}
class TestClass10{
static void m10() {
filter_rt003a.log1("entered: m10");
}
}
class TestClass11 extends TestClass10{
static void m11() {
filter_rt003a.log1("entered: m11");
TestClass10.m10();
}
}
class Thread1filter_rt003a extends Thread {
String tName = null;
public Thread1filter_rt003a(String threadName) {
super(threadName);
tName = threadName;
}
public void run() {
filter_rt003a.log1(" 'run': enter :: threadName == " + tName);
synchronized(filter_rt003a.waitnotifyObj) {
filter_rt003a.waitnotifyObj.notify();
}
synchronized(filter_rt003a.lockObj1) {
TestClass11.m11();
}
filter_rt003a.log1(" 'run': exit :: threadName == " + tName);
return;
}
}
class TestClass20{
static void m20() {
filter_rt003a.log1("entered: m20");
}
}
class TestClass21 extends TestClass20{
static void m21() {
filter_rt003a.log1("entered: m21");
TestClass20.m20();
}
}
class Thread2filter_rt003a extends Thread {
String tName = null;
public Thread2filter_rt003a(String threadName) {
super(threadName);
tName = threadName;
}
public void run() {
filter_rt003a.log1(" 'run': enter :: threadName == " + tName);
synchronized(filter_rt003a.waitnotifyObj) {
filter_rt003a.waitnotifyObj.notify();
}
synchronized(filter_rt003a.lockObj2) {
TestClass21.m21();
}
filter_rt003a.log1(" 'run': exit :: threadName == " + tName);
return;
}
}
======================================================
// log
==> nsk/jdi/StepRequest/addClassFilter_rt/filter_rt003 TESTING BEGINS
--> debugger: breakpointForCommunication
debugee.stderr> **> debuggee: debuggee started!
debugee.stderr> **> debuggee: 'run': enter :: threadName == thread1
debugee.stderr> **> debuggee: 'run': enter :: threadName == thread2
debugee.stderr> **> debuggee: methodForCommunication();----1
==> nsk/jdi/StepRequest/addClassFilter_rt/filter_rt003 :::::: case: # 0
--> debugger: ......setting up StepRequest:
--> debugger: thread: instance of
nsk.jdi.StepRequest.addClassFilter_rt.Thread1filter_rt003a(name='thread1', id=75); property:
StepRequest1
--> debugger: StepRequest has been set up
--> debugger: ......setting up StepRequest:
--> debugger: thread: instance of
nsk.jdi.StepRequest.addClassFilter_rt.Thread2filter_rt003a(name='thread2', id=74); property:
StepRequest2
--> debugger: StepRequest has been set up
--> debugger: ......waiting for StepEvent in expected thread
debugee.stderr> **> debuggee: entered: m11
debugee.stderr> **> debuggee: entered: m10
debugee.stderr> **> debuggee: 'run': exit :: threadName == thread1
debugee.stderr> **> debuggee: entered: m21
debugee.stderr> **> debuggee: entered: m20
debugee.stderr> **> debuggee: 'run': exit :: threadName == thread2
debugee.stderr> **> debuggee: methodForCommunication();
# ERROR: ##> debugger: ERROR: new event is not StepEvent
# ERROR: ##> debugger: ERROR: new event is BreakpointEvent
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
debugee.stderr> **> debuggee: debuggee exits
==> nsk/jdi/StepRequest/addClassFilter_rt/filter_rt003 TESTING ENDS
----------------------------------------------------------------------
======================================================================
- duplicates
-
JDK-4629548 Deferred StepRequests missed in multithreaded debuggee
- Resolved