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 2007/05/28 13:29:05 UTC
svn commit: r542204 - in /harmony/enhanced/drlvm/trunk:
src/test/regression/H3982/ src/test/regression/excludes/ vm/vmcore/src/jvmti/
Author: gshimansky
Date: Mon May 28 04:29:04 2007
New Revision: 542204
URL: http://svn.apache.org/viewvc?view=rev&rev=542204
Log:
Applied HARMONY-3982 [drlvm][jvmti] JVMTI GetAllStackTraces, GetThreadListStackTraces functions work incorrectly
Added:
harmony/enhanced/drlvm/trunk/src/test/regression/H3982/
harmony/enhanced/drlvm/trunk/src/test/regression/H3982/EmptyStackTrace.cpp (with props)
harmony/enhanced/drlvm/trunk/src/test/regression/H3982/EmptyStackTrace.java (with props)
harmony/enhanced/drlvm/trunk/src/test/regression/H3982/run.test.xml (with props)
Modified:
harmony/enhanced/drlvm/trunk/src/test/regression/excludes/exclude.linux.x86_64
harmony/enhanced/drlvm/trunk/src/test/regression/excludes/exclude.windows.x86_64
harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_stack.cpp
Added: harmony/enhanced/drlvm/trunk/src/test/regression/H3982/EmptyStackTrace.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/src/test/regression/H3982/EmptyStackTrace.cpp?view=auto&rev=542204
==============================================================================
--- harmony/enhanced/drlvm/trunk/src/test/regression/H3982/EmptyStackTrace.cpp (added)
+++ harmony/enhanced/drlvm/trunk/src/test/regression/H3982/EmptyStackTrace.cpp Mon May 28 04:29:04 2007
@@ -0,0 +1,309 @@
+/**
+ * Test case for GetStackTrace() function on threads with empty stack.
+ * 1. Creates native thread.
+ * 2. Attaches it to vm.
+ * 3. From exception callback retrievs all threads and finds the attached one.
+ * 4. Calls GetStackTrace() for the attached thread. It should return success
+ * code as RI does.
+ */
+
+#include <iostream>
+#include <string.h>
+#include <jvmti.h>
+
+using namespace std;
+
+#define PACKAGE "org/apache/harmony/drlvm/tests/regression/h3982/"
+
+static const char* EXCEPTION_CLASS = "L" PACKAGE "InvokeAgentException;";
+
+static char* ATTACHED_THREAD_NAME = "attached_thread";
+static const jint MAX_FRAME_COUNT = 100;
+static JavaVM* java_vm = NULL;
+
+static bool attached = false;
+static bool finish = false;
+
+static bool start_native_thread();
+
+#define TURN_EVENT(event, state) { \
+ jvmtiError err = turn_event(jvmti, event, state, #event); \
+ if (JVMTI_ERROR_NONE != err) return; \
+}
+
+#define CHECK_RESULT(func) \
+ if (JVMTI_ERROR_NONE != err) { \
+ cerr << "[JvmtiAgent] ERROR: " << #func << " failed with error: " << err << endl; \
+ return; \
+ }
+
+#define CHECK_JNI3(result, func, error_code) { \
+ if (jni->ExceptionCheck()) { \
+ cerr << "[JvmtiAgent] ERROR: unexpected exception in " << #func << endl; \
+ jni->ExceptionDescribe(); \
+ return error_code; \
+ } \
+ if (! (result)) { \
+ cerr << "[JvmtiAgent] ERROR: get NULL in " << #func << endl; \
+ return error_code; \
+ } \
+}
+
+#define CHECK_JNI(result, func) CHECK_JNI3(result, func, )
+
+static void set_passed_state(JNIEnv* jni)
+{
+ cerr << endl << "TEST PASSED" << endl << endl;
+
+ jclass cl = jni->FindClass(PACKAGE "Status");
+ CHECK_JNI(cl, FindClass);
+
+ jfieldID testGroup_field = jni->GetStaticFieldID(cl, "status", "Z");
+ CHECK_JNI(testGroup_field, GetStaticFieldID);
+
+ jni->SetStaticBooleanField(cl, testGroup_field, JNI_TRUE);
+ CHECK_JNI(true, SetStaticBooleanField);
+}
+
+static jvmtiError turn_event(jvmtiEnv* jvmti, jvmtiEvent event, bool state,
+ const char* event_name)
+{
+ jvmtiError err;
+ err = jvmti->SetEventNotificationMode(state ? JVMTI_ENABLE : JVMTI_DISABLE,
+ event, NULL);
+ if (JVMTI_ERROR_NONE != err) {
+ cerr << "[JvmtiAgent] ERROR: unable to " << (state ? "en" : "dis")
+ << "able " << event_name
+ << endl;
+ }
+
+ return err;
+}
+
+static void thread_func(void* arg)
+{
+ cerr << endl << "native thread stated" << endl << endl;
+
+ JavaVMAttachArgs attach_args = {JNI_VERSION_1_2, ATTACHED_THREAD_NAME, NULL};
+
+ JNIEnv* jni;
+ if (0 != java_vm->AttachCurrentThread((void**) &jni,
+ (void*) &attach_args)) {
+ cerr << "[native thread] ERROR: unable to attach the thread" << endl;
+ return;
+ }
+
+ attached = true;
+
+ int a = 9;
+
+ while (! finish);
+
+ if (0 != java_vm->DetachCurrentThread()) {
+ cerr << "[native thread] ERROR: unable to detach the thread" << endl;
+ return;
+ }
+
+
+ cerr << endl << "native thread finished" << endl << endl;
+}
+
+
+static void JNICALL VMInit(jvmtiEnv* jvmti, JNIEnv* jni, jthread thread)
+{
+ cerr << endl << "==> VM Init callback" << endl;
+
+ cerr << "starting native thread..." << endl << flush;
+
+ if (! start_native_thread()) {
+ cerr << "[JvmtiAgent] ERROR: unable to run native thread" << endl;
+ return;
+ }
+
+ TURN_EVENT(JVMTI_EVENT_EXCEPTION, true);
+
+ cerr << endl << "==> VM Init finished" << endl << flush;
+}
+
+static void check_stack_trace(jvmtiEnv *jvmti, JNIEnv* jni)
+{
+ jvmtiError err;
+
+ if (! attached) {
+ cerr << "wait for native thraad to attach..." << endl << flush;
+ while (! attached);
+ }
+
+ jint threads_count;
+ jthread* threads;
+
+ err = jvmti->GetAllThreads(&threads_count, &threads);
+ CHECK_RESULT(GetAllThreads);
+
+ int attached_theads_count = 0;
+ jthread attached_thread;
+
+ cerr << endl << "All threads:" << endl;
+ for (int i = 0; i < threads_count; i++) {
+ jvmtiThreadInfo thread_info;
+
+ err = jvmti->GetThreadInfo(threads[i], &thread_info);
+ CHECK_RESULT(GetThreadInfo);
+
+
+ jvmtiThreadGroupInfo group_info;
+
+ err = jvmti->GetThreadGroupInfo(thread_info.thread_group, &group_info);
+ CHECK_RESULT(GetThreadDroupInfo);
+
+ cerr << i << ":\t" << thread_info.name << "\tin group: "
+ << group_info.name << endl;
+
+ if (0 == strcmp(ATTACHED_THREAD_NAME, thread_info.name)) {
+ attached_theads_count ++;
+ attached_thread = threads[i];
+ }
+ }
+
+ if (attached_theads_count != 1) {
+ cerr << "FAILED: found " << attached_theads_count
+ << " attached threads; expected 1" << endl;
+ return;
+ }
+
+ jvmtiFrameInfo frames[MAX_FRAME_COUNT];
+ jint frame_count;
+
+ err = jvmti->GetStackTrace(attached_thread, 0, MAX_FRAME_COUNT, frames,
+ &frame_count);
+ CHECK_RESULT(GetStackTrace);
+
+ cerr << endl << "Atached thread stack [" << frame_count << "]" << endl;
+ for (int i = 0; i < frame_count; i++) {
+ char* method_name;
+ char* method_sig;
+
+ err = jvmti->GetMethodName(frames[i].method, &method_name, &method_sig,
+ NULL);
+ CHECK_RESULT(GetMethodName);
+
+ cerr << i << ":\t" << method_name << method_sig << endl;
+
+ }
+
+ set_passed_state(jni);
+
+}
+
+static void JNICALL
+Exception(jvmtiEnv *jvmti,
+ JNIEnv* jni,
+ jthread thread,
+ jmethodID method,
+ jlocation location,
+ jobject exception,
+ jmethodID catch_method,
+ jlocation catch_location)
+{
+ jvmtiError err;
+
+ jclass exn_class = jni->GetObjectClass(exception);
+ CHECK_JNI(exn_class, GetObjectClass);
+
+ char* class_name = NULL;
+ err = jvmti->GetClassSignature(exn_class, &class_name, NULL);
+ CHECK_RESULT(GetClassSignature);
+
+ if (0 != strcmp(EXCEPTION_CLASS, class_name))
+ return;
+
+ cerr << endl << "==> Exception callback" << endl;
+ cerr << " for class: " << class_name << endl;
+
+ TURN_EVENT(JVMTI_EVENT_EXCEPTION, false);
+
+ check_stack_trace(jvmti, jni);
+
+ finish = true;
+}
+
+JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM *vm, char *options, void *reserved)
+{
+ java_vm = vm;
+ jvmtiEnv *jvmti = NULL;
+ jvmtiError err;
+
+ // Get JVMTI interface pointer
+ jint iRes = vm->GetEnv((void**)&jvmti, JVMTI_VERSION);
+ if (JNI_OK != iRes) {
+ cerr << "[JvmtiAgent] ERROR: unable to get JVMTI environment" << endl;
+ return -1;
+ }
+
+ // Set events callbacks
+ jvmtiEventCallbacks callbacks;
+ memset(&callbacks, 0, sizeof(jvmtiEventCallbacks));
+
+ callbacks.VMInit = VMInit;
+ callbacks.Exception = Exception;
+
+ err = jvmti->SetEventCallbacks(&callbacks, sizeof(jvmtiEventCallbacks));
+ if (JVMTI_ERROR_NONE != err) {
+ cerr << "[JvmtiAgent] ERROR: unable to register event callbacks" << endl;
+ return -1;
+ }
+
+ err = jvmti->SetEventNotificationMode(JVMTI_ENABLE,
+ JVMTI_EVENT_VM_INIT, NULL);
+ if (JVMTI_ERROR_NONE != err) {
+ cerr << "[JvmtiAgent] ERROR: unable to enable VMInit event"
+ << endl;
+ return -1;
+ }
+
+ // Set capabilities
+ jvmtiCapabilities capabilities;
+ memset(&capabilities, 0, sizeof(jvmtiCapabilities));
+ capabilities.can_generate_exception_events = 1;
+
+ err = jvmti->AddCapabilities(&capabilities);
+ if (JVMTI_ERROR_NONE != err) {
+ cerr << "[JvmtiAgent] ERROR: unable to possess capabilities" << endl;
+ return -1;
+ }
+
+ // Agent initialized successfully
+ return 0;
+}
+
+#if defined WIN32 || defined _WIN32
+
+#include <process.h>
+
+static bool start_native_thread()
+{
+ uintptr_t handle = _beginthread(&thread_func, 0, NULL);
+
+ if (handle == 0 || handle == 1 || handle == -1)
+ return false;
+
+ return true;
+}
+
+#else
+
+static bool start_native_thread()
+{
+ pthread_t thread;
+ int r;
+
+ r = pthread_create(&thread, NULL, (void*(*)(void*))thread_func, NULL);
+
+ if (0 != r)
+ return false;
+
+ return true;
+}
+
+#endif
+//
Propchange: harmony/enhanced/drlvm/trunk/src/test/regression/H3982/EmptyStackTrace.cpp
------------------------------------------------------------------------------
svn:eol-style = native
Added: harmony/enhanced/drlvm/trunk/src/test/regression/H3982/EmptyStackTrace.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/src/test/regression/H3982/EmptyStackTrace.java?view=auto&rev=542204
==============================================================================
--- harmony/enhanced/drlvm/trunk/src/test/regression/H3982/EmptyStackTrace.java (added)
+++ harmony/enhanced/drlvm/trunk/src/test/regression/H3982/EmptyStackTrace.java Mon May 28 04:29:04 2007
@@ -0,0 +1,34 @@
+package org.apache.harmony.drlvm.tests.regression.h3982;
+
+import junit.framework.TestCase;
+
+/**
+ * Test case for GetStackTrace() function on threads with empty stack.
+ */
+public class EmptyStackTrace extends TestCase {
+
+ public static void main(String args[]) {
+ (new EmptyStackTrace()).test();
+ }
+
+ public void test() {
+
+ try {
+ System.err.println("[Java]: Throwing an exception to invoke agent");
+ // pass execution to the agent
+ throw new InvokeAgentException();
+ } catch (Exception e) {
+ System.err.println("[Java]: Exception caught");
+ }
+
+ System.err.println("[Java]: test done");
+ assertTrue(Status.status);
+ }
+}
+
+class InvokeAgentException extends Exception {}
+
+class Status {
+ /** the field should be modified by jvmti agent to determine test result. */
+ public static boolean status = false;
+}
Propchange: harmony/enhanced/drlvm/trunk/src/test/regression/H3982/EmptyStackTrace.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: harmony/enhanced/drlvm/trunk/src/test/regression/H3982/run.test.xml
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/src/test/regression/H3982/run.test.xml?view=auto&rev=542204
==============================================================================
--- harmony/enhanced/drlvm/trunk/src/test/regression/H3982/run.test.xml (added)
+++ harmony/enhanced/drlvm/trunk/src/test/regression/H3982/run.test.xml Mon May 28 04:29:04 2007
@@ -0,0 +1,9 @@
+<project name="RUN HARMONY-3982 Regression Test">
+ <target name="run-test">
+ <!-- use special launcher for JVMTI tests -->
+ <run-jvmti-test
+ test="org.apache.harmony.drlvm.tests.regression.h3982.EmptyStackTrace"
+ agent="EmptyStackTrace"/>
+ </target>
+</project>
+
Propchange: harmony/enhanced/drlvm/trunk/src/test/regression/H3982/run.test.xml
------------------------------------------------------------------------------
svn:eol-style = native
Modified: harmony/enhanced/drlvm/trunk/src/test/regression/excludes/exclude.linux.x86_64
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/src/test/regression/excludes/exclude.linux.x86_64?view=diff&rev=542204&r1=542203&r2=542204
==============================================================================
--- harmony/enhanced/drlvm/trunk/src/test/regression/excludes/exclude.linux.x86_64 (original)
+++ harmony/enhanced/drlvm/trunk/src/test/regression/excludes/exclude.linux.x86_64 Mon May 28 04:29:04 2007
@@ -11,4 +11,6 @@
H3894
# Exclude this test because JVMTI is not implemented for x86_64 in JIT mode yet
H3909
+# Exclude this test because JVMTI is not implemented for x86_64 in JIT mode yet
+H3982
Modified: harmony/enhanced/drlvm/trunk/src/test/regression/excludes/exclude.windows.x86_64
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/src/test/regression/excludes/exclude.windows.x86_64?view=diff&rev=542204&r1=542203&r2=542204
==============================================================================
--- harmony/enhanced/drlvm/trunk/src/test/regression/excludes/exclude.windows.x86_64 (original)
+++ harmony/enhanced/drlvm/trunk/src/test/regression/excludes/exclude.windows.x86_64 Mon May 28 04:29:04 2007
@@ -9,5 +9,6 @@
H3894
# Exclude this test because JVMTI is not implemented for x86_64 in JIT mode yet
H3909
-
+# Exclude this test because JVMTI is not implemented for x86_64 in JIT mode yet
+H3982
Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_stack.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_stack.cpp?view=diff&rev=542204&r1=542203&r2=542204
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_stack.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_stack.cpp Mon May 28 04:29:04 2007
@@ -209,6 +209,14 @@
JavaStackIterator jsi(vm_thread);
+ // to be complient with RI we must break the spec.
+ // if stack is empty and start_depth is 0 RI doesn't return
+ // JVMTI_ERROR_ILLEGAL_ARGUMENT as it is required by spec.
+ if (start == 0 && ! jsi) {
+ *count_ptr = 0;
+ return JVMTI_ERROR_NONE;
+ }
+
jsi += start;
if (! jsi)