You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by gs...@apache.org on 2006/11/24 14:10:27 UTC
svn commit: r478866 - in /harmony/enhanced/drlvm/trunk: build/make/
build/make/targets/ vm/tests/jvmti/Breakpoint1/ vm/tests/jvmti/SingleStep1/
Author: gshimansky
Date: Fri Nov 24 05:10:26 2006
New Revision: 478866
URL: http://svn.apache.org/viewvc?view=rev&rev=478866
Log:
Applied HARMONY-2293 [drlvm][jvmti] New tests for JVMTI: Breakpoint & SingleStep
New tests passed on ubuntu, fedora and windows 2003 server
Added:
harmony/enhanced/drlvm/trunk/vm/tests/jvmti/Breakpoint1/
harmony/enhanced/drlvm/trunk/vm/tests/jvmti/Breakpoint1/Breakpoint1.java
harmony/enhanced/drlvm/trunk/vm/tests/jvmti/Breakpoint1/agent.cpp
harmony/enhanced/drlvm/trunk/vm/tests/jvmti/Breakpoint1/agent.h
harmony/enhanced/drlvm/trunk/vm/tests/jvmti/Breakpoint1/breakpoint.cpp
harmony/enhanced/drlvm/trunk/vm/tests/jvmti/SingleStep1/
harmony/enhanced/drlvm/trunk/vm/tests/jvmti/SingleStep1/SingleStep1.java
harmony/enhanced/drlvm/trunk/vm/tests/jvmti/SingleStep1/agent.cpp
harmony/enhanced/drlvm/trunk/vm/tests/jvmti/SingleStep1/agent.h
harmony/enhanced/drlvm/trunk/vm/tests/jvmti/SingleStep1/singlestep.cpp
Modified:
harmony/enhanced/drlvm/trunk/build/make/ (props changed)
harmony/enhanced/drlvm/trunk/build/make/targets/jvmti.test.xml
Propchange: harmony/enhanced/drlvm/trunk/build/make/
------------------------------------------------------------------------------
--- svn:ignore (original)
+++ svn:ignore Fri Nov 24 05:10:26 2006
@@ -1 +1,2 @@
tmp
+junit*.properties
Modified: harmony/enhanced/drlvm/trunk/build/make/targets/jvmti.test.xml
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/build/make/targets/jvmti.test.xml?view=diff&rev=478866&r1=478865&r2=478866
==============================================================================
--- harmony/enhanced/drlvm/trunk/build/make/targets/jvmti.test.xml (original)
+++ harmony/enhanced/drlvm/trunk/build/make/targets/jvmti.test.xml Fri Nov 24 05:10:26 2006
@@ -78,6 +78,9 @@
<select os="lnx">
<linkerarg value="-lstdc++" />
</select>
+ <select os="win">
+ <compilerarg value="/GX" />
+ </select>
<fileset dir="@{directory}">
<include name="**/*.cpp" />
</fileset>
Added: harmony/enhanced/drlvm/trunk/vm/tests/jvmti/Breakpoint1/Breakpoint1.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/tests/jvmti/Breakpoint1/Breakpoint1.java?view=auto&rev=478866
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/tests/jvmti/Breakpoint1/Breakpoint1.java (added)
+++ harmony/enhanced/drlvm/trunk/vm/tests/jvmti/Breakpoint1/Breakpoint1.java Fri Nov 24 05:10:26 2006
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Pavel Rebriy
+ */
+
+package Breakpoint1;
+
+import junit.framework.TestCase;
+
+public class Breakpoint1 extends TestCase {
+ static boolean status = false;
+
+ static public void main(String args[]) {
+ Breakpoint1 instance = new Breakpoint1();
+ instance.test();
+ instance.test();
+ if(status) {
+ System.out.println("Test passed!");
+ } else {
+ System.out.println("Test failed!");
+ }
+ assertTrue(status);
+ return;
+ }
+
+ public void test() {
+ /*
+ * Simple sequention of operations for
+ * creating breakpoints here.
+ */
+ int a = 2;
+ int b = a + 3;
+ int c = b + 4;
+ int d = c + 5;
+ int e = d + 6;
+ int f = e + 7;
+ int g = f + 9;
+ int h = g + 10;
+ int i = h + 11;
+ int j = i + 12;
+ assertTrue(status);
+ return;
+ }
+}
+
+
Added: harmony/enhanced/drlvm/trunk/vm/tests/jvmti/Breakpoint1/agent.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/tests/jvmti/Breakpoint1/agent.cpp?view=auto&rev=478866
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/tests/jvmti/Breakpoint1/agent.cpp (added)
+++ harmony/enhanced/drlvm/trunk/vm/tests/jvmti/Breakpoint1/agent.cpp Fri Nov 24 05:10:26 2006
@@ -0,0 +1,127 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Pavel Rebriy
+ */
+
+#include "agent.h"
+
+#define CHECK_CAP(obtained, needed, jvmti_cap) \
+ if(!obtained.jvmti_cap) { \
+ REPORT( "Cannot set capability: "#jvmti_cap ); \
+ return JNI_ERR; \
+ } \
+ needed.jvmti_cap = 1;
+
+void JNICALL
+agent_callback_MethodEntry( jvmtiEnv* jvmti_env,
+ JNIEnv* jni_env,
+ jthread thread,
+ jmethodID method);
+
+void JNICALL
+agent_callback_Breakpoint( jvmtiEnv* jvmti_env,
+ JNIEnv* jni_env,
+ jthread thread,
+ jmethodID method,
+ jlocation location);
+
+static inline jint
+set_agent_capabilities(jvmtiEnv * jvmti_env)
+{
+ // get VM capabilities
+ jvmtiCapabilities vm_cap;
+ jvmtiError result = jvmti_env->GetPotentialCapabilities(&vm_cap);
+ if (result != JVMTI_ERROR_NONE) {
+ REPORT( "get potential capabilities" );
+ return JNI_ERR;
+ }
+
+ jvmtiCapabilities need_cap = {0};
+ CHECK_CAP(vm_cap, need_cap, can_generate_breakpoint_events);
+ CHECK_CAP(vm_cap, need_cap, can_generate_method_entry_events);
+ CHECK_CAP(vm_cap, need_cap, can_get_line_numbers);
+
+ result = jvmti_env->AddCapabilities(&need_cap);
+ if (result != JVMTI_ERROR_NONE) {
+ REPORT( "set needed capabilities" );
+ return JNI_ERR;
+ }
+ return JNI_OK;
+}
+
+static inline jint
+set_agent_events(jvmtiEnv * jvmti_env)
+{
+ jvmtiEventCallbacks callbacks;
+ memset(&callbacks, 0, sizeof(callbacks));
+
+ // set event callbacks
+ callbacks.MethodEntry = &agent_callback_MethodEntry;
+ callbacks.Breakpoint = &agent_callback_Breakpoint;
+ jvmtiError result = jvmti_env->SetEventCallbacks(&callbacks, (jint)sizeof(callbacks));
+ if( result != JVMTI_ERROR_NONE ) {
+ REPORT("set events callbacks");
+ return JNI_ERR;
+ }
+
+ // set MethodEntry event
+ result = jvmti_env->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_METHOD_ENTRY, NULL);
+ if( result != JVMTI_ERROR_NONE ) {
+ REPORT("enable MethodEntry event");
+ return JNI_ERR;
+ }
+
+ // set Breakpoint event
+ result = jvmti_env->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_BREAKPOINT, NULL);
+ if( result != JVMTI_ERROR_NONE ) {
+ REPORT("enable Breakpoint event");
+ return JNI_ERR;
+ }
+
+ return JNI_OK;
+}
+
+JNIEXPORT jint JNICALL
+Agent_OnLoad(JavaVM *vm, char *options, void *reserved)
+{
+ // get JVMTI enviroment
+ jvmtiEnv * jvmti_env;
+ DEBUG("Getting JVMTI enviroment... ");
+ if( vm->GetEnv( (void**)&jvmti_env, JVMTI_VERSION_1_0) != JNI_OK ) {
+ REPORT( "get JVMTI enviroment" );
+ return JNI_OK;
+ }
+ DEBUG("done!");
+
+ // set capabilities
+ DEBUG("Setting capabilities... ");
+ if( set_agent_capabilities(jvmti_env) != JNI_OK ) {
+ return JNI_OK;
+ }
+ DEBUG("done!");
+
+ // set events
+ DEBUG("Setting events... ");
+ if( set_agent_events(jvmti_env) != JNI_OK ) {
+ return JNI_OK;
+ }
+ DEBUG("done!");
+
+ return JNI_OK;
+}
Added: harmony/enhanced/drlvm/trunk/vm/tests/jvmti/Breakpoint1/agent.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/tests/jvmti/Breakpoint1/agent.h?view=auto&rev=478866
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/tests/jvmti/Breakpoint1/agent.h (added)
+++ harmony/enhanced/drlvm/trunk/vm/tests/jvmti/Breakpoint1/agent.h Fri Nov 24 05:10:26 2006
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Pavel Rebriy
+ */
+
+#ifndef _JVMTI_AGENT_H_
+#define _JVMTI_AGENT_H_
+
+#include <stdlib.h>
+#include <string.h>
+#include <iostream>
+#include "jvmti.h"
+
+#ifdef NDEBUG
+#define DEBUG(str)
+#else // NDEBUG
+#define DEBUG(str) std::cout << "DEBUG: " << str << std::endl;
+#endif // NDEBUG
+
+#define REPORT(str) std::cerr << "ERROR: " << str << std::endl;
+#define ERR_REPORT(str) \
+ { \
+ std::cerr << "ERROR: " << str << std::endl; \
+ error = true; \
+ }
+
+#define CHECK_ERROR() \
+ if(error) { \
+ return; \
+ }
+
+#endif // _JVMTI_AGENT_H_
Added: harmony/enhanced/drlvm/trunk/vm/tests/jvmti/Breakpoint1/breakpoint.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/tests/jvmti/Breakpoint1/breakpoint.cpp?view=auto&rev=478866
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/tests/jvmti/Breakpoint1/breakpoint.cpp (added)
+++ harmony/enhanced/drlvm/trunk/vm/tests/jvmti/Breakpoint1/breakpoint.cpp Fri Nov 24 05:10:26 2006
@@ -0,0 +1,233 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Pavel Rebriy
+ */
+
+#include "agent.h"
+
+static jint lines[] = {50, 55};
+static bool error = false;
+
+static void
+set_test_success( jvmtiEnv* jvmti_env,
+ JNIEnv* jni_env,
+ jmethodID method)
+{
+ CHECK_ERROR();
+
+ DEBUG("Setting success == true... ");
+ jclass klass;
+ jvmtiError result = jvmti_env->GetMethodDeclaringClass(method, &klass);
+ if(result != JVMTI_ERROR_NONE) {
+ ERR_REPORT("get method class");
+ return;
+ }
+ jfieldID field = jni_env->GetStaticFieldID(klass, "status", "Z");
+ if( !field ) {
+ ERR_REPORT("get 'status' field");
+ return;
+ }
+ jni_env->SetStaticBooleanField(klass, field, JNI_TRUE);
+ DEBUG("done");
+ return;
+}
+
+void JNICALL
+agent_callback_MethodEntry( jvmtiEnv* jvmti_env,
+ JNIEnv* jni_env,
+ jthread thread,
+ jmethodID method)
+{
+ CHECK_ERROR();
+
+ char *name;
+ char *descr;
+ jvmtiError result = jvmti_env->GetMethodName(method, &name, &descr, NULL);
+ if( result != JVMTI_ERROR_NONE
+ || strcmp(name, "test") || strcmp(descr, "()V" ) )
+ {
+ return;
+ }
+ jclass klass;
+ result = jvmti_env->GetMethodDeclaringClass(method, &klass);
+ if(result != JVMTI_ERROR_NONE) {
+ ERR_REPORT("get method class");
+ return;
+ }
+ char *class_name;
+ result = jvmti_env->GetClassSignature(klass, &class_name, NULL);
+ if(result != JVMTI_ERROR_NONE
+ || strcmp(class_name, "LBreakpoint1/Breakpoint1;"))
+ {
+ ERR_REPORT("wrong MethodEntry callback");
+ return;
+ }
+ DEBUG("MethodEntry callback is called for Breakpoint1.Breakpoint1.test()");
+
+ DEBUG("Disabling MethodEntry event... ");
+ result = jvmti_env->SetEventNotificationMode(JVMTI_DISABLE,
+ JVMTI_EVENT_METHOD_ENTRY, NULL);
+ if(result != JVMTI_ERROR_NONE) {
+ ERR_REPORT("disable MethodEntry event");
+ return;
+ }
+ DEBUG("done");
+
+ DEBUG("Getting line number table...");
+ jvmtiLineNumberEntry *table;
+ jint number;
+ result = jvmti_env->GetLineNumberTable( method, &number, &table );
+ if(result != JVMTI_ERROR_NONE) {
+ ERR_REPORT("get line number table");
+ return;
+ }
+ DEBUG("done");
+
+ DEBUG("Setting breakpoints... ");
+ for(int index = 0; index < 2; index++) {
+ bool is_set = false;
+ for(jint count = 0; count < number - 1; count++) {
+ if(lines[index] >= table[count].line_number
+ && lines[index] < table[count + 1].line_number )
+ {
+ is_set = true;
+ DEBUG("Setting breakpoint on line " << lines[index] << "...");
+ result = jvmti_env->SetBreakpoint(method, table[count].start_location);
+ if(result != JVMTI_ERROR_NONE) {
+ ERR_REPORT("set breakpoint on line " << lines[index]);
+ return;
+ }
+ DEBUG("done");
+ break;
+ }
+ }
+ if(!is_set) {
+ ERR_REPORT("set breakpoint on line " << lines[index]);
+ return;
+ }
+ }
+ DEBUG("Setting breakpoints... done");
+
+ DEBUG("Deallocating line number table... ");
+ result = jvmti_env->Deallocate((unsigned char*)table);
+ if(result != JVMTI_ERROR_NONE) {
+ ERR_REPORT("Deallocate failed!");
+ return;
+ }
+ DEBUG("done");
+
+ return;
+}
+
+void JNICALL
+agent_callback_Breakpoint( jvmtiEnv* jvmti_env,
+ JNIEnv* jni_env,
+ jthread thread,
+ jmethodID method,
+ jlocation location)
+{
+ CHECK_ERROR();
+
+ char *name;
+ char *descr;
+ jvmtiError result = jvmti_env->GetMethodName(method, &name, &descr, NULL);
+ if( result != JVMTI_ERROR_NONE
+ || strcmp(name, "test") || strcmp(descr, "()V" ) )
+ {
+ return;
+ }
+ jclass klass;
+ result = jvmti_env->GetMethodDeclaringClass(method, &klass);
+ if(result != JVMTI_ERROR_NONE) {
+ ERR_REPORT("get method class");
+ return;
+ }
+ char *class_name;
+ result = jvmti_env->GetClassSignature(klass, &class_name, NULL);
+ if(result != JVMTI_ERROR_NONE
+ || strcmp(class_name, "LBreakpoint1/Breakpoint1;"))
+ {
+ ERR_REPORT("wrong Breakpoint callback");
+ return;
+ }
+ DEBUG("Breakpoint occupied in function Breakpoint1.Breakpoint1.test()");
+
+ DEBUG("Getting line number table...");
+ jvmtiLineNumberEntry *table;
+ jint number;
+ result = jvmti_env->GetLineNumberTable( method, &number, &table );
+ if(result != JVMTI_ERROR_NONE) {
+ ERR_REPORT("get line number table");
+ return;
+ }
+ DEBUG("done");
+
+ DEBUG("Checking breakpoints...");
+ for(jint count = 0; count < number - 1; count++) {
+ if(location >= table[count].start_location
+ && location < table[count + 1].start_location)
+ {
+ DEBUG("Breakpoint on line " << table[count].line_number);
+ static bool is_occupied = false;
+ if( !is_occupied ) {
+ if( lines[0] == table[count].line_number ) {
+ // the first breakpoint is occupied
+ is_occupied = true;
+ DEBUG("Clearing the first breakpoint...");
+ result = jvmti_env->ClearBreakpoint(method, location);
+ if(result != JVMTI_ERROR_NONE) {
+ ERR_REPORT("clear breakpoint");
+ return;
+ }
+ DEBUG("done");
+ break;
+ } else {
+ ERR_REPORT("wrong breakpoint callback");
+ return;
+ }
+ } else {
+ if( lines[1] == table[count].line_number ) {
+ // the second breakpoint is occupied
+ DEBUG("Disabling Breakpoint event... ");
+ result = jvmti_env->SetEventNotificationMode(JVMTI_DISABLE,
+ JVMTI_EVENT_BREAKPOINT, NULL);
+ if(result != JVMTI_ERROR_NONE) {
+ ERR_REPORT("disable Breakpoint event");
+ return;
+ }
+ DEBUG("done");
+ set_test_success(jvmti_env, jni_env, method);
+ break;
+ } else {
+ ERR_REPORT("wrong breakpoint callback");
+ return;
+ }
+ }
+ }
+ }
+
+ DEBUG("Deallocating line number table... ");
+ result = jvmti_env->Deallocate((unsigned char*)table);
+ if(result != JVMTI_ERROR_NONE) {
+ ERR_REPORT("Deallocate failed!");
+ return;
+ }
+ DEBUG("done");
+ return;
+}
Added: harmony/enhanced/drlvm/trunk/vm/tests/jvmti/SingleStep1/SingleStep1.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/tests/jvmti/SingleStep1/SingleStep1.java?view=auto&rev=478866
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/tests/jvmti/SingleStep1/SingleStep1.java (added)
+++ harmony/enhanced/drlvm/trunk/vm/tests/jvmti/SingleStep1/SingleStep1.java Fri Nov 24 05:10:26 2006
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Pavel Rebriy
+ */
+
+package SingleStep1;
+
+import junit.framework.TestCase;
+
+public class SingleStep1 extends TestCase {
+
+ static boolean status = false;
+
+ public static void main(String[] args) {
+ new SingleStep1().test();
+ if (status) {
+ System.out.println("Test passed!");
+ } else {
+ System.out.println("Test failed!");
+ }
+ assertTrue(status);
+ }
+
+ public void test() {
+ // set the first breakpoint to the next line
+ Object obj = new Object();
+ int z = 10;
+ z = z * 2;
+ // set the second breakpoint to the next line
+ System.out.println("done: " + z + obj);
+ assertTrue(status);
+ return;
+ }
+}
Added: harmony/enhanced/drlvm/trunk/vm/tests/jvmti/SingleStep1/agent.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/tests/jvmti/SingleStep1/agent.cpp?view=auto&rev=478866
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/tests/jvmti/SingleStep1/agent.cpp (added)
+++ harmony/enhanced/drlvm/trunk/vm/tests/jvmti/SingleStep1/agent.cpp Fri Nov 24 05:10:26 2006
@@ -0,0 +1,129 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Pavel Rebriy
+ */
+
+#include "agent.h"
+
+#define CHECK_CAP(obtained, needed, jvmti_cap) \
+ if(!obtained.jvmti_cap) { \
+ REPORT( "Cannot set capability: "#jvmti_cap ); \
+ return JNI_ERR; \
+ } \
+ needed.jvmti_cap = 1;
+
+void JNICALL
+agent_callback_MethodEntry( jvmtiEnv* jvmti_env,
+ JNIEnv* jni_env,
+ jthread thread,
+ jmethodID method);
+
+void JNICALL
+agent_callback_Breakpoint( jvmtiEnv* jvmti_env,
+ JNIEnv* jni_env,
+ jthread thread,
+ jmethodID method,
+ jlocation location);
+
+void JNICALL
+agent_callback_SingleStep( jvmtiEnv * jvmti_env,
+ JNIEnv * jni_env,
+ jthread thread,
+ jmethodID method,
+ jlocation location);
+
+static inline jint
+set_agent_capabilities(jvmtiEnv * jvmti_env)
+{
+ // get VM capabilities
+ jvmtiCapabilities vm_cap;
+ jvmtiError result = jvmti_env->GetPotentialCapabilities(&vm_cap);
+ if (result != JVMTI_ERROR_NONE) {
+ REPORT( "get potential capabilities" );
+ return JNI_ERR;
+ }
+
+ jvmtiCapabilities need_cap = {0};
+ CHECK_CAP(vm_cap, need_cap, can_generate_breakpoint_events);
+ CHECK_CAP(vm_cap, need_cap, can_generate_method_entry_events);
+ CHECK_CAP(vm_cap, need_cap, can_get_line_numbers);
+ CHECK_CAP(vm_cap, need_cap, can_generate_single_step_events);
+
+ result = jvmti_env->AddCapabilities(&need_cap);
+ if (result != JVMTI_ERROR_NONE) {
+ REPORT( "set needed capabilities" );
+ return JNI_ERR;
+ }
+ return JNI_OK;
+}
+
+static inline jint
+set_agent_events(jvmtiEnv * jvmti_env)
+{
+ jvmtiEventCallbacks callbacks;
+ memset(&callbacks, 0, sizeof(callbacks));
+
+ // set event callbacks
+ callbacks.MethodEntry = &agent_callback_MethodEntry;
+ callbacks.Breakpoint = &agent_callback_Breakpoint;
+ callbacks.SingleStep = &agent_callback_SingleStep;
+ jvmtiError result = jvmti_env->SetEventCallbacks(&callbacks, (jint)sizeof(callbacks));
+ if( result != JVMTI_ERROR_NONE ) {
+ REPORT("set events callbacks");
+ return JNI_ERR;
+ }
+
+ // set MethodEntry event
+ result = jvmti_env->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_METHOD_ENTRY, NULL);
+ if( result != JVMTI_ERROR_NONE ) {
+ REPORT("enable MethodEntry event");
+ return JNI_ERR;
+ }
+
+ return JNI_OK;
+}
+
+JNIEXPORT jint JNICALL
+Agent_OnLoad(JavaVM *vm, char *options, void *reserved)
+{
+ // get JVMTI enviroment
+ jvmtiEnv * jvmti_env;
+ DEBUG("Getting JVMTI enviroment... ");
+ if( vm->GetEnv( (void**)&jvmti_env, JVMTI_VERSION_1_0) != JNI_OK ) {
+ REPORT( "get JVMTI enviroment" );
+ return JNI_OK;
+ }
+ DEBUG("done!");
+
+ // set capabilities
+ DEBUG("Setting capabilities... ");
+ if( set_agent_capabilities(jvmti_env) != JNI_OK ) {
+ return JNI_OK;
+ }
+ DEBUG("done!");
+
+ // set events
+ DEBUG("Setting events... ");
+ if( set_agent_events(jvmti_env) != JNI_OK ) {
+ return JNI_OK;
+ }
+ DEBUG("done!");
+
+ return JNI_OK;
+}
Added: harmony/enhanced/drlvm/trunk/vm/tests/jvmti/SingleStep1/agent.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/tests/jvmti/SingleStep1/agent.h?view=auto&rev=478866
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/tests/jvmti/SingleStep1/agent.h (added)
+++ harmony/enhanced/drlvm/trunk/vm/tests/jvmti/SingleStep1/agent.h Fri Nov 24 05:10:26 2006
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Pavel Rebriy
+ */
+
+#ifndef _JVMTI_AGENT_H_
+#define _JVMTI_AGENT_H_
+
+#include <stdlib.h>
+#include <string.h>
+#include <iostream>
+#include "jvmti.h"
+
+#ifdef NDEBUG
+#define DEBUG(str)
+#else // NDEBUG
+#define DEBUG(str) std::cout << "DEBUG: " << str << std::endl;
+#endif // NDEBUG
+
+#define REPORT(str) std::cerr << "ERROR: " << str << std::endl;
+#define ERR_REPORT(str) \
+ { \
+ std::cerr << "ERROR: " << str << std::endl; \
+ error = true; \
+ }
+
+#define CHECK_ERROR() \
+ if(error) { \
+ return; \
+ }
+
+#endif // _JVMTI_AGENT_H_
Added: harmony/enhanced/drlvm/trunk/vm/tests/jvmti/SingleStep1/singlestep.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/tests/jvmti/SingleStep1/singlestep.cpp?view=auto&rev=478866
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/tests/jvmti/SingleStep1/singlestep.cpp (added)
+++ harmony/enhanced/drlvm/trunk/vm/tests/jvmti/SingleStep1/singlestep.cpp Fri Nov 24 05:10:26 2006
@@ -0,0 +1,332 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Pavel Rebriy
+ */
+
+#include "agent.h"
+
+static jint lines[] = {43, 47, 44};
+static bool stop_after_constructor = false;
+static bool error = false;
+
+static void
+set_test_success( jvmtiEnv* jvmti_env,
+ JNIEnv* jni_env,
+ jmethodID method)
+{
+ CHECK_ERROR();
+
+ DEBUG("Setting success == true... ");
+ jclass klass;
+ jvmtiError result = jvmti_env->GetMethodDeclaringClass(method, &klass);
+ if(result != JVMTI_ERROR_NONE) {
+ ERR_REPORT("get method class");
+ return;
+ }
+ jfieldID field = jni_env->GetStaticFieldID(klass, "status", "Z");
+ if( !field ) {
+ ERR_REPORT("get 'status' field");
+ return;
+ }
+ jni_env->SetStaticBooleanField(klass, field, JNI_TRUE);
+ DEBUG("done");
+ return;
+}
+
+void JNICALL
+agent_callback_SingleStep( jvmtiEnv * jvmti_env,
+ JNIEnv * jni_env,
+ jthread thread,
+ jmethodID method,
+ jlocation location)
+{
+ CHECK_ERROR();
+
+ char *name;
+ char *descr;
+ jvmtiError result = jvmti_env->GetMethodName(method, &name, &descr, NULL);
+ if( result != JVMTI_ERROR_NONE
+ || strcmp(name, "test") || strcmp(descr, "()V" ) )
+ {
+ return;
+ }
+ jclass klass;
+ result = jvmti_env->GetMethodDeclaringClass(method, &klass);
+ if(result != JVMTI_ERROR_NONE) {
+ ERR_REPORT("get method class");
+ return;
+ }
+ char *class_name;
+ result = jvmti_env->GetClassSignature(klass, &class_name, NULL);
+ if(result != JVMTI_ERROR_NONE
+ || strcmp(class_name, "LSingleStep1/SingleStep1;"))
+ {
+ ERR_REPORT("wrong MethodEntry callback");
+ return;
+ }
+ DEBUG("SingleStep callback is called");
+
+ DEBUG("Getting line number table...");
+ jvmtiLineNumberEntry *table;
+ jint number;
+ result = jvmti_env->GetLineNumberTable( method, &number, &table );
+ if(result != JVMTI_ERROR_NONE) {
+ ERR_REPORT("get line number table");
+ return;
+ }
+ DEBUG("done");
+
+ DEBUG("Checking SingleStep location...");
+ for(jint count = 0; count < number - 1; count++) {
+ if(location >= table[count].start_location
+ && location < table[count + 1].start_location)
+ {
+ DEBUG("SingleStep location is on line " << table[count].line_number);
+ if( lines[2] == table[count].line_number ) {
+ // SingleStep location is after new Object().
+ DEBUG("Disabling SingleStep event... ");
+ result = jvmti_env->SetEventNotificationMode(JVMTI_DISABLE,
+ JVMTI_EVENT_SINGLE_STEP, NULL);
+ if(result != JVMTI_ERROR_NONE) {
+ ERR_REPORT("disable SingleStep event");
+ return;
+ }
+ DEBUG("done");
+ stop_after_constructor = true;
+ }
+ break;
+ }
+ }
+
+ DEBUG("Deallocating line number table... ");
+ result = jvmti_env->Deallocate((unsigned char*)table);
+ if(result != JVMTI_ERROR_NONE) {
+ ERR_REPORT("deallocate line number");
+ return;
+ }
+ DEBUG("done");
+
+ return;
+}
+
+
+void JNICALL
+agent_callback_MethodEntry( jvmtiEnv* jvmti_env,
+ JNIEnv* jni_env,
+ jthread thread,
+ jmethodID method)
+{
+ CHECK_ERROR();
+
+ char *name;
+ char *descr;
+ jvmtiError result = jvmti_env->GetMethodName(method, &name, &descr, NULL);
+ if( result != JVMTI_ERROR_NONE
+ || strcmp(name, "test") || strcmp(descr, "()V" ) )
+ {
+ return;
+ }
+ jclass klass;
+ result = jvmti_env->GetMethodDeclaringClass(method, &klass);
+ if(result != JVMTI_ERROR_NONE) {
+ ERR_REPORT("get method class");
+ return;
+ }
+ char *class_name;
+ result = jvmti_env->GetClassSignature(klass, &class_name, NULL);
+ if(result != JVMTI_ERROR_NONE
+ || strcmp(class_name, "LSingleStep1/SingleStep1;"))
+ {
+ ERR_REPORT("wrong MethodEntry callback");
+ return;
+ }
+ DEBUG("MethodEntry callback is called for SingleStep1.SingleStep1.test()");
+
+ DEBUG("Disabling MethodEntry event... ");
+ result = jvmti_env->SetEventNotificationMode(JVMTI_DISABLE,
+ JVMTI_EVENT_METHOD_ENTRY, NULL);
+ if(result != JVMTI_ERROR_NONE) {
+ ERR_REPORT("disable MethodEntry event");
+ return;
+ }
+ DEBUG("done");
+
+ DEBUG("Enabling Breakpoint event... ");
+ result = jvmti_env->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_BREAKPOINT, NULL);
+ if( result != JVMTI_ERROR_NONE ) {
+ ERR_REPORT("enable Breakpoint event");
+ return;
+ }
+ DEBUG("done");
+
+ DEBUG("Getting line number table...");
+ jvmtiLineNumberEntry *table;
+ jint number;
+ result = jvmti_env->GetLineNumberTable( method, &number, &table );
+ if(result != JVMTI_ERROR_NONE) {
+ ERR_REPORT("get line number table");
+ return;
+ }
+ DEBUG("done");
+
+ DEBUG("Setting breakpoints... ");
+ for(int index = 0; index < 2; index++) {
+ bool is_set = false;
+ for(jint count = 0; count < number - 1; count++) {
+ if(lines[index] >= table[count].line_number
+ && lines[index] < table[count + 1].line_number )
+ {
+ is_set = true;
+ DEBUG("Setting breakpoint on line " << lines[index] << "...");
+ result = jvmti_env->SetBreakpoint(method, table[count].start_location);
+ if(result != JVMTI_ERROR_NONE) {
+ ERR_REPORT("set breakpoint on line " << lines[index]);
+ return;
+ }
+ DEBUG("done");
+ break;
+ }
+ }
+ if(!is_set) {
+ ERR_REPORT("set breakpoint on line " << lines[index]);
+ return;
+ }
+ }
+ DEBUG("Setting breakpoints... done");
+
+ DEBUG("Deallocating line number table... ");
+ result = jvmti_env->Deallocate((unsigned char*)table);
+ if(result != JVMTI_ERROR_NONE) {
+ ERR_REPORT("deallocate line number");
+ return;
+ }
+ DEBUG("done");
+
+ return;
+}
+
+void JNICALL
+agent_callback_Breakpoint( jvmtiEnv* jvmti_env,
+ JNIEnv* jni_env,
+ jthread thread,
+ jmethodID method,
+ jlocation location)
+{
+ CHECK_ERROR();
+
+ char *name;
+ char *descr;
+ jvmtiError result = jvmti_env->GetMethodName(method, &name, &descr, NULL);
+ if( result != JVMTI_ERROR_NONE
+ || strcmp(name, "test") || strcmp(descr, "()V" ) )
+ {
+ return;
+ }
+ jclass klass;
+ result = jvmti_env->GetMethodDeclaringClass(method, &klass);
+ if(result != JVMTI_ERROR_NONE) {
+ ERR_REPORT("get method class");
+ return;
+ }
+ char *class_name;
+ result = jvmti_env->GetClassSignature(klass, &class_name, NULL);
+ if(result != JVMTI_ERROR_NONE
+ || strcmp(class_name, "LSingleStep1/SingleStep1;"))
+ {
+ ERR_REPORT("wrong Breakpoint callback");
+ return;
+ }
+ DEBUG("Breakpoint occupied in function SingleStep1.SingleStep1.test()");
+
+ DEBUG("Getting line number table...");
+ jvmtiLineNumberEntry *table;
+ jint number;
+ result = jvmti_env->GetLineNumberTable( method, &number, &table );
+ if(result != JVMTI_ERROR_NONE) {
+ ERR_REPORT("get line number table");
+ return;
+ }
+ DEBUG("done");
+
+ DEBUG("Checking breakpoints...");
+ for(jint count = 0; count < number - 1; count++) {
+ if(location >= table[count].start_location
+ && location < table[count + 1].start_location)
+ {
+ DEBUG("Breakpoint on line " << table[count].line_number);
+ static bool is_occupied = false;
+ if( !is_occupied ) {
+ if( lines[0] == table[count].line_number ) {
+ // the first breakpoint is occupied
+ is_occupied = true;
+ DEBUG("Enabling SingleStep event... ");
+ result = jvmti_env->SetEventNotificationMode(JVMTI_ENABLE,
+ JVMTI_EVENT_SINGLE_STEP, NULL);
+ if(result != JVMTI_ERROR_NONE) {
+ ERR_REPORT("enable SingleStep event");
+ return;
+ }
+ DEBUG("done");
+ break;
+ } else {
+ ERR_REPORT("wrong breakpoint callback");
+ return;
+ }
+ } else {
+ if( lines[1] == table[count].line_number ) {
+ // the second breakpoint is occupied
+ DEBUG("Disabling Breakpoint event... ");
+ result = jvmti_env->SetEventNotificationMode(JVMTI_DISABLE,
+ JVMTI_EVENT_BREAKPOINT, NULL);
+ if(result != JVMTI_ERROR_NONE) {
+ ERR_REPORT("disable Breakpoint event");
+ return;
+ }
+ DEBUG("done");
+ if(!stop_after_constructor) {
+ DEBUG("Disabling SingleStep event... ");
+ result = jvmti_env->SetEventNotificationMode(JVMTI_DISABLE,
+ JVMTI_EVENT_BREAKPOINT, NULL);
+ if(result != JVMTI_ERROR_NONE) {
+ ERR_REPORT("disable Breakpoint event");
+ return;
+ }
+ DEBUG("done");
+ } else {
+ set_test_success(jvmti_env, jni_env, method);
+ }
+ break;
+ } else {
+ ERR_REPORT("wrong breakpoint callback");
+ return;
+ }
+ }
+ }
+ }
+
+ DEBUG("Deallocating line number table... ");
+ result = jvmti_env->Deallocate((unsigned char*)table);
+ if(result != JVMTI_ERROR_NONE) {
+ ERR_REPORT("deallocate line number");
+ return;
+ }
+ DEBUG("done");
+
+ return;
+}