/******************************************************************************* An implementation of the Java Debug Wire Protocol (JDWP) for JOP Copyright (C) 2007 Paulo Abadie Guedes This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *******************************************************************************/ package debug; import java.io.IOException; import com.jopdesign.sys.Native; import debug.io.EmbeddedOutputStream; public class TestJopDebugKernel { public static void test1() { System.out.println("Hello JOP world!!!"); System.out.println("Testing make now."); Exception e = new Exception("Message:)"); System.out.println("Stack trace: " + e.getMessage()); e.printStackTrace(); } public static void printValue(int value) { printLine(); printCurrentFramePointer("printValue(int value)"); System.out.print(" Value is: "); System.out.println(value); } public static void test2_read_write() { int sp, x; // int x1, x2, x3, x4,x5,x6; // x1 = 1; // x2 = 2; // x3 = 3; // x4 = 4444; // x5 = 5; // x6 = 6; // dummyCall(x1+x2+x3+x4+x5+x6); printLine(); System.out.println("Hello JOP world!!!"); System.out.println(" 2) Testing read/write now."); sp = Native.getSP(); // System.out.println("Current SP for test2_read_write(): " + sp); printCurrentFramePointer("test2_read_write()"); x = 16; printValue(x); readPrintAndIncrement(1); if(x == 17) { System.out.println("Worked as expected."); } else { System.out.println("Failure: wrong value!!! Shoulb be 17."); } printValue(x); int framePointer = JopDebugKernel.getCurrentFramePointer(); printStackDepth("test2_read_write ", framePointer); sp = sp + x; System.out.println(" Making the two variables live until here (x+sp): " + sp); } /** * */ static void printLine() { System.out.println("----------------------------------------"); } /** * Get the variable at index "index" on the stack frame of the * method calling this method. Read, print and increment it. * * @param index */ public static void readPrintAndIncrement(int index) { int x1, x2, x3, x4,x5,x6; x1 = 1; x2 = 2; x3 = 3; x4 = 5555; x5 = 5; x6 = 6; // x1 = x1 + x2 + x3 + x4 + x5 + x6; dummyCall(x1+x2+x3+x4+x5+x6); int sp; int callersFP; int frame; int value; printLine(); // sp = Native.getSP(); // System.out.println("Current SP for readPrintAndIncrement(): " + sp); printCurrentFramePointer("readPrintAndIncrement(int index)"); callersFP = JopDebugKernel.getFramePointerOfCallerMethod(); System.out.println(" getFramePointerOfCallerMethod(): " + callersFP); // frame = getCurrentFramePointer(); // frame = getNextFramePointer(frame); // System.out.println(" Should be the same as: " + frame); System.out.println(" Will get field now..."); index= 1; value = JopDebugKernel.getLocalVariable(callersFP, index); System.out.println(" The value of field #" + index + " is :" + value); // dumpCallStack(); value++; JopDebugKernel.setLocalVariable(callersFP, index, value); } /** * */ private static void printCurrentFramePointer(String message) { // int x1, x2, x3, x4,x5,x6; // x1 = 1; // x2 = 2; // x3 = 3; // x4 = 4; // x5 = 5; // x6 = 6; // x1 = x1 + x2 + x3 + x4 + x5 + x6; // dummyCall(x1+x2+x3+x4+x5+x6); int currentFramePointer = JopDebugKernel.getCurrentFramePointer(); currentFramePointer = JopDebugKernel.getNextFramePointer(currentFramePointer); System.out.print(message); System.out.println(" Current frame pointer: " + currentFramePointer); } public static void dumpCallStack() { int i, value; int count = 0; // for(i = 0; i < 256; i++) // for(i = 0; i < 512; i++) for(i = 0; i < 256; i++) { value = Native.rdIntMem(i); // value = Native.rdMem(i); if(value == 0) { count ++; } else { if(count > 0) { System.out.println(count + " values are zero"); count = 0; } System.out.println("stack[" + i + "] = " + value); } } if(count > 0) { System.out.println(count + " values are zero"); count = 0; } // Exception e = new Exception(); // e.printStackTrace(); //testStack(12); // ok, we still have room for 12 empty frames //testStack(13); // but with 13 stack... overflow! printCurrentFramePointer("dumpCallStack()"); // System.out.println(" Tracing: "); // JVMHelp.trace(); } // public static void printCallStackInfo() // { // int currentFrame = getCurrentFramePointer(); // // while(isFirstFrame(currentFramePointer)) // } // public static void checkIsFirstFrame(String message, int framePointer, boolean expected) { boolean result = JopDebugKernel.isFirstFrame(framePointer); String auxMessage = message; // TODO: someone need to check JOP basic classes // compiling the line below with the modified // classpath BREAKS THE javac COMPILER!!!. // It is not a compiler issue since // it compiles without problems with the regular Java classpath. // Really strange, need to be checked inside JOP classes. // probably something with Object, String or StringBuffer. // System.out.println(message + " result: " + result); // auxMessage = message + " result: " + result; auxMessage = message + " result: "; System.out.print(auxMessage); System.out.println(result); if(result != expected) { System.out.println(" NOT AS EXPECTED!!! FAILURE HERE"); } } /** * A simple method to test how much space is still left on the stack. * Compile and call it with different values until the stack overflows. * Simple. Raw. Direct. Maybe a hack... but worked;). * * @param index */ private static void testStack(int index) { // int framePointer = getCurrentFramePointer(); // printStackDepth("testStack(" + index + "): ", framePointer); printStackDepth("testStack(" + index + "): ", JopDebugKernel.getCurrentFramePointer()); if(index > 1) { testStack(index - 1); } } private static void dummyCall(int x) { } public static final void test3_checkFirstFrame() { int framePointer = JopDebugKernel.getCurrentFramePointer(); checkIsFirstFrame("test3_checkFirstFrame() ", framePointer, false); } public static final void traverseStack(int framePointer) { int count = 0; while(JopDebugKernel.isFirstFrame(framePointer) == false) { System.out.println(" Frame " + count + ": pointer = " + framePointer); framePointer = JopDebugKernel.getNextFramePointer(framePointer); } } public static final void printStackDepth(String message, int framePointer) { int depth = JopDebugKernel.getStackDepth(framePointer); System.out.println(message + " Stack depth: " + depth + " Frame: " + framePointer); } public static void test4_read_write() { printLine(); System.out.println("test4_read_write()"); // TestObject object; int objectRef; int frameIndex; TestObject object= new TestObject(); // object= new TestObject(); // object.setValue(16); frameIndex = JopDebugKernel.getCurrentFramePointer(); objectRef = JopDebugKernel.getLocalVariable(frameIndex, 0); // System.out.println(" Value: " + object.getValue()); // readPrintAndIncrementField(objectRef, 0); // readPrintAndIncrementField(object, 0); // System.out.println(" Value: " + object.getValue()); JopDebugKernel.breakpoint(); } public static final void readPrintAndIncrementField(int object, int fieldIndex) { printLine(); int num; // handle needs indirection object = Native.rdMem(object); num = Native.rdMem(object + fieldIndex); System.out.println(" Field value: " + num); num++; Native.wrMem(num, object + fieldIndex); // num = getClassReference(object); // System.out.println("Class reference: " + num); // int constantPool = getConstantPoolFromClassReference(classReference); JopDebugKernel.breakpoint(); } /** * */ private static void test5_checkJopSimIO() { EmbeddedOutputStream stream = new EmbeddedOutputStream(System.out); try { int test = System.in.read(); System.out.println(" Success! read one byte"); System.out.println(" Echo:"); System.out.println(test); // sendPacketPrintByte((byte)test); stream.writeInt((byte)test); test = 0x0f0f0f0f; stream.writeInt(test); } catch (IOException exception) { exception.printStackTrace(); } } private static void test6_checkCurrentMethodStructure() { // the parameters below are not used. They exist just to allow // the test6_helpMethod() to check if it's possible to query // the number of parameters of a method. test6_helpMethod(1,2); } /** * This method exists just to be called by * test6_checkCurrentMethodStructure() method, in order to test the * methods (from JopDebugKernel) which inspect data inside the * method structure. Wow, that was confusing. * * @param x * @param y */ private static void test6_helpMethod(int x, int y) { int methodPointer, methodArgCount, methodLocalsCount; methodPointer = JopDebugKernel.getCurrentMethodPointer(); printLine(); System.out.print("Current method pointer: "); System.out.println(methodPointer); methodArgCount = JopDebugKernel.getMethodArgCount(methodPointer); if(methodArgCount != 2) { System.out.print("Failure! should be 2 but found: "); System.out.println(methodArgCount); } methodLocalsCount = JopDebugKernel.getMethodLocalsCount(methodPointer); if(methodLocalsCount != 3) { System.out.print("Failure! should be 3 but found: "); System.out.println(methodLocalsCount); } JopDebugKernel.dumpMethodStruct(methodPointer); JopDebugKernel.dumpMethodBody(methodPointer); printLine(); } /** * @param args */ public static void main(String[] args) { int x = 10, y = 10, z = 10; System.out.println(" Starting..."); int sp = Native.getSP(); System.out.println(" SP of main(String[] args) is: " + sp); printCurrentFramePointer("main(String[] args)"); // dumpCallStack(); // int x = 3333; // int threadID = Native. // System.out.println(" Thread ID of main: " + threadID); // test1(); // test2_read_write(); // get the current frame pointer and // assign "20" to the local field at index 1 (the second one). // the first field is at index 0 and ir the "args" array. // int framePointer; // framePointer = getCurrentFramePointer(); // setLocal_Variable(framePointer, 1, 20); // System.out.println(" after direct assignment to the stack frame, x = " + x); // // checkIsFirstFrame("main ", framePointer, true); // // test3_checkFirstFrame(); // // printStackDepth("main ", framePointer); // // x = getNumLocalsFromFrame(framePointer); // System.out.println(" Num.locals in main: " + x); // // testStack(8); // //test4_read_write(); // test5_checkJopSimIO(); test6_checkCurrentMethodStructure(); System.out.print(" LocalVP:"); System.out.print(JopDebugKernel.getCurrentVP()); System.out.print(" x = "); System.out.println(x); // JopDebugKernel.breakpoint(); // EmbeddedOutputStream.testEmbeddedPrinter(); TestObject testObject = new TestObject(); System.out.print("TestObject value is: "); System.out.println(testObject.getValue0()); test4_read_write(); System.out.println("Will run method: identity"); x = TestObject.identity(x); System.out.println("Will run method: increment"); x = TestObject.increment(x); System.out.println("Will run method: testInc"); x = TestObject.testInc(); System.out.println("Will run method: getConstant"); x = TestObject.getConstant(); } }