Skip to main content

Crached when call opc_invokespecial?!

4 replies [Last post]
jiankercn
Offline
Joined: 2008-04-02
Points: 0

When CDC1.0, the case of opc_invokespecial as fallows:
case opc_invokespecial: {
CVMMethodBlock* new_mb = mb;
CVMClassBlock* currClass = CVMeeGetCurrentFrameCb(ee);
if (CVMisSpecialSuperCall(currClass, mb)) {
new_mb = CVMcbMethodTableSlot(CVMcbSuperclass(currClass),
CVMmbMethodTableIndex(mb));
}
if (mb == new_mb) {
newOpcode = opc_invokenonvirtual_quick;
} else {
newOpcode = opc_invokesuper_quick;
operand1 = CVMmbMethodTableIndex(mb) >> 8;
operand2 = CVMmbMethodTableIndex(mb) & 0xFF;
changesOperands = CVM_TRUE;
}
break;
And I can do the TCK test with all passed.
But when CDC-MR2, the implementation of opc_invokespecial like this:
case opc_invokespecial: {
CVMMethodBlock* new_mb = mb;
CVMMethodTypeID methodID = CVMmbNameAndTypeID(mb);
CVMClassBlock* currClass = CVMeeGetCurrentFrameCb(ee);
if (CVMisSpecialSuperCall(currClass, mb)) {
/* Find matching declared method in a super class. */
new_mb = CVMlookupSpecialSuperMethod(ee, currClass, methodID);
}
if (mb == new_mb) {
if (CVMmbClassBlock(mb) == CVMsystemClass(java_lang_Object) &&
methodID == CVMglobals.initTid) {
/* we can ignore all calls to Object. */
newOpcode = opc_invokeignored_quick;
CVMassert(CVMmbArgsSize(mb) == 1);
operand1 = 1;
operand2 = CVM_TRUE; /* null check needed */
changesOperands = CVM_TRUE;
} else {
newOpcode = opc_invokenonvirtual_quick;
}
} else {
newOpcode = opc_invokesuper_quick;
operand1 = CVMmbMethodTableIndex(new_mb) >> 8;
operand2 = CVMmbMethodTableIndex(new_mb) & 0xFF;
changesOperands = CVM_TRUE;
}
break;
But when run to the new_mb = CVMlookupSpecialSuperMethod(ee, currClass, methodID); the cvm is crached(recived a signal SIGSEGV).
I don't no why?!

And the test case:
import java.io.PrintStream;

public class invokespecial00601m1 {

public static int run(String argv[], PrintStream out) {

if (instantiateNegative("invokespecial00601m10n", AbstractMethodError.class, argv, out) != 0/*STATUS_PASSED*/)
return 2/*STATUS_FAILED*/;

return 0/*STATUS_PASSED*/;
}

public static int instantiateNegative(String testName, Class expectedException, String argv[], PrintStream out) {

Class badClass = null;
try {
badClass = Class.forName("javasoft.sqe.tests.vm.instr.invokespecial.invokespecial006.invokespecial00601m1." + testName);
try {
Object obj=badClass.newInstance();
} catch (ThreadDeath e) {
throw e;
} catch (Throwable e) {
if (expectedException.isInstance(e)) {
out.println("Passed with runtime exception: " + e);
return 0/*STATUS_PASSED*/;
} else {
out.println("Failed with unexpected runtime exception: " + e);
return 2/*STATUS_FAILED*/;
}
}
} catch (ThreadDeath e) {
throw e;
} catch (Throwable e) {
if (expectedException.isInstance(e)) {
out.println("Passed with loading exception: " + e);
return 0/*STATUS_PASSED*/;
} else {
out.println("Failed with unexpected loading exception: " + e);
return 2/*STATUS_FAILED*/;
}
}
out.println("Failed to reject invalid class " + testName);
return 2/*STATUS_FAILED*/;
}

public static void main(String args[]) {
System.exit(run(args, System.out) + 95/*STATUS_TEMP*/);
}
}
}
Can anybody help me?Thank you very much!

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
meng_xx
Offline
Joined: 2005-08-17
Points: 0

hi jiankercn,

i got the same problem. have you find any reason?

br!
meng

cjplummer
Offline
Joined: 2006-10-16
Points: 0

This code hasn't changed in over a year and has passed the TCK test in question many times on many different platforms. If this is your own port, possibly you have a bug that has introduced a memory corruption. You'll need to use a debugger to get more details as to why it is crashing.

Chris

meng_xx
Offline
Joined: 2005-08-17
Points: 0

hi jiankercn, here is my analysis.

there is an assertion fail in CVMlookupSpecialSuperMethod. not "crash".

first of all, please exam the src of the invokespecial006 test case, and CVMlookupSpecialSuperMethod carefully. otherwise you won't know what i am talking about in the following.

the invokespecial006 test case produced an illegal subclass which didn't implement one abstract method in the super class. when CVM call the missing method in the subclass, CVM searches for the method in the super class, the search function is CVMlookupSpecialSuperMethod. however super class does not impl the method either. finally CVM failed to find the impl until it reaches java.lang.Object. in this situation, the current interpreter.c suppose (say made an assertion mb!=NULL) that means the method must be found in super classes. if the mb is NULL (not found) the assertion failed , and results in signal 11 in the following steps.

the correct way should be throw AbstractMethodError, instead of assertion fail, maybe just in CVMlookupSpecialSuperMethod function, or CVMlookupSpecialSuperMethod return null, and somewhere else check it and throw expected error.

Mr. Chris, how do you think?

cjplummer
Offline
Joined: 2006-10-16
Points: 0

I see now you were using CDC 1.0. In the latest OSS source, the test passes as expected:

Passed with runtime exception: java.lang.AbstractMethodError: javasoft.sqe.tests.vm.instr.invokespecial.invokespecial006.invokespecial00601m1.invokespecial00601m11na.mtd()V

I'm not even sure if this test is part of the CDC TCK 1.0. In any case, this forum is really more for the current CDC release (mainly phoneME). For CDC 1.0 support, you'll probably need to work with Java Licensing Engineering.

Chris