harmony-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From gshiman...@apache.org
Subject svn commit: r563554 - in /harmony/enhanced/drlvm/trunk: src/test/regression/H3341/ src/test/regression/excludes/ vm/vmcore/include/ vm/vmcore/src/jvmti/
Date Tue, 07 Aug 2007 17:01:43 GMT
Author: gshimansky
Date: Tue Aug  7 10:01:41 2007
New Revision: 563554

URL: http://svn.apache.org/viewvc?view=rev&rev=563554
Log:
Applied patch from HARMONY-3341
[drlvm][jvmti] StopThread() does not interrupt thread in Object.wait(timeout) until timeout
expired


Added:
    harmony/enhanced/drlvm/trunk/src/test/regression/H3341/
    harmony/enhanced/drlvm/trunk/src/test/regression/H3341/StopThreadInWait.cpp   (with props)
    harmony/enhanced/drlvm/trunk/src/test/regression/H3341/StopThreadInWait.java   (with props)
    harmony/enhanced/drlvm/trunk/src/test/regression/H3341/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/include/jvmti_internal.h
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_internal.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_thread.cpp

Added: harmony/enhanced/drlvm/trunk/src/test/regression/H3341/StopThreadInWait.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/src/test/regression/H3341/StopThreadInWait.cpp?view=auto&rev=563554
==============================================================================
--- harmony/enhanced/drlvm/trunk/src/test/regression/H3341/StopThreadInWait.cpp (added)
+++ harmony/enhanced/drlvm/trunk/src/test/regression/H3341/StopThreadInWait.cpp Tue Aug  7
10:01:41 2007
@@ -0,0 +1,156 @@
+/**
+ * Test case for StopThread() jvmti function applied to thread that hangs on
+ * Object.wait().
+ */
+
+#include <iostream>
+#include <jvmti.h>
+
+using namespace std;
+
+#define PACKAGE "org/apache/harmony/drlvm/tests/regression/h3341/"
+
+static const char* EXCEPTION_CLASS = "L" PACKAGE "InvokeAgentException;";
+
+#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 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 JNICALL VMInit(jvmtiEnv* jvmti, JNIEnv* jni, jthread thread)
+{
+    cerr << endl << "==> VM Init callback" << endl;
+
+    TURN_EVENT(JVMTI_EVENT_EXCEPTION, true);
+}
+
+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);
+
+    jfieldID thread_field = jni->GetFieldID(exn_class, "thread",
+            "Ljava/lang/Thread;");
+    CHECK_JNI(thread_field, GetFieldID);
+
+    jthread test_thread = jni->GetObjectField(exception, thread_field);
+    CHECK_JNI(test_thread, GetObjectField);
+
+    jfieldID exc_field = jni->GetFieldID(exn_class, "stopException",
+            "Ljava/lang/Throwable;");
+    CHECK_JNI(exc_field, GetFieldID);
+
+    jthread stop_exception = jni->GetObjectField(exception, exc_field);
+    CHECK_JNI(stop_exception, GetObjectField);
+
+    cerr << "Stopping test thread..." << endl;
+
+    err = jvmti->StopThread(test_thread, stop_exception);
+    CHECK_RESULT(StopThread);
+}
+
+JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM *vm, char *options, void *reserved)
+{
+    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;
+    capabilities.can_signal_thread = 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;
+}

Propchange: harmony/enhanced/drlvm/trunk/src/test/regression/H3341/StopThreadInWait.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Added: harmony/enhanced/drlvm/trunk/src/test/regression/H3341/StopThreadInWait.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/src/test/regression/H3341/StopThreadInWait.java?view=auto&rev=563554
==============================================================================
--- harmony/enhanced/drlvm/trunk/src/test/regression/H3341/StopThreadInWait.java (added)
+++ harmony/enhanced/drlvm/trunk/src/test/regression/H3341/StopThreadInWait.java Tue Aug 
7 10:01:41 2007
@@ -0,0 +1,99 @@
+package org.apache.harmony.drlvm.tests.regression.h3341;
+
+import junit.framework.TestCase;
+
+/**
+ * Test case for StopThread() jvmti function applied to thread that hangs on
+ * Object.wait().
+ * Checks that StopThread() forces target thread to exit wait() and throw the
+ * requested exception immediately before the wait() timeout is over.
+ * Since we test thread synchronization methods behaviour the test doesn't use
+ * synchronization object's for it's own purposes. Thus It's execution is based
+ * on timeouts.
+ */
+public class StopThreadInWait extends TestCase {
+
+    static final int TIMEOUT_FOR_WAIT = 10000;
+    static final int TIMEOUT_BEFORE_STOPPING = 1000;
+    static final int TIMEOUT_FOR_EXCEPTION = 1000;
+
+    static boolean tooLate = false;
+
+    public static void main(String args[]) {
+        (new StopThreadInWait()).test();
+    }
+
+    public void test() {
+        Thread waitingThread = new WaitingThread();
+        waitingThread.start();
+
+        try {
+            Thread.sleep(TIMEOUT_BEFORE_STOPPING);
+            try {
+                System.err.println("[Java]: Throwing an exception");
+                // pass execution to the agent
+                throw new InvokeAgentException(waitingThread,
+                        new ThreadDeath());
+            } catch (Exception e) {
+                System.err.println("[Java]: Exception caught");
+            }
+
+            Thread.sleep(TIMEOUT_FOR_EXCEPTION);
+            tooLate = true;
+
+            System.err.println("[Java]: joining test_thread...");
+            waitingThread.join();
+        } catch(InterruptedException exc) {
+            exc.printStackTrace();
+        }
+
+        System.err.println("[Java]: test done");
+        assertTrue(Status.status);
+    }
+}
+
+class WaitingThread extends Thread {
+
+    public WaitingThread() {
+        super();
+    }
+
+    public void run() {
+        Object lock = new Object();
+
+        synchronized(lock) {
+            try {
+                System.out.println("[java]: test thread falling in wait");
+                lock.wait(StopThreadInWait.TIMEOUT_FOR_WAIT);
+            } catch(ThreadDeath exc) {
+                if (! StopThreadInWait.tooLate) {
+                    Status.status = true;
+
+                    System.out.println("[java]: test thread has caught " +
+                            "ThreadDeath exception in time");
+                } else {
+                    System.out.println("[java]: test thread has caught " +
+                            "ThreadDeath exception too late");
+                }
+            } catch(Throwable exc) {
+                exc.printStackTrace();
+            }
+        }
+    }
+};
+
+class InvokeAgentException extends Exception {
+
+    Thread thread;
+    Throwable stopException;
+
+    InvokeAgentException(Thread thread, Throwable exception) {
+        this.thread = thread;
+        stopException = 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/H3341/StopThreadInWait.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: harmony/enhanced/drlvm/trunk/src/test/regression/H3341/run.test.xml
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/src/test/regression/H3341/run.test.xml?view=auto&rev=563554
==============================================================================
--- harmony/enhanced/drlvm/trunk/src/test/regression/H3341/run.test.xml (added)
+++ harmony/enhanced/drlvm/trunk/src/test/regression/H3341/run.test.xml Tue Aug  7 10:01:41
2007
@@ -0,0 +1,9 @@
+<project name="RUN HARMONY-3341 Regression Test">
+    <target name="run-test">
+        <!-- use special launcher for JVMTI tests -->
+        <run-jvmti-test
+            test="org.apache.harmony.drlvm.tests.regression.h3341.StopThreadInWait"
+            agent="StopThreadInWait"/>
+    </target>
+</project>
+

Propchange: harmony/enhanced/drlvm/trunk/src/test/regression/H3341/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=563554&r1=563553&r2=563554
==============================================================================
--- 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 Tue Aug
 7 10:01:41 2007
@@ -18,4 +18,6 @@
 H3982
 # Exclude this test because JVMTI is not implemented for x86_64 in JIT mode yet
 H4512
+# Exclude this test because JVMTI is not implemented for x86_64 in JIT mode yet
+H3341
  

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=563554&r1=563553&r2=563554
==============================================================================
--- 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 Tue Aug
 7 10:01:41 2007
@@ -17,4 +17,7 @@
 H3982
 # Exclude this test because JVMTI is not implemented for x86_64 in JIT mode yet
 H4512
+# Exclude this test because JVMTI is not implemented for x86_64 in JIT mode yet
+H3341
+
 

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/include/jvmti_internal.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/include/jvmti_internal.h?view=diff&rev=563554&r1=563553&r2=563554
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/include/jvmti_internal.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/include/jvmti_internal.h Tue Aug  7 10:01:41 2007
@@ -379,6 +379,7 @@
 void jvmti_remove_single_step_breakpoints(DebugUtilsTI *ti, jvmti_thread_t jvmti_thread);
 
 // Object check functions
+Boolean is_valid_throwable_object(jthread thread);
 Boolean is_valid_thread_object(jthread thread);
 Boolean is_valid_thread_group_object(jthreadGroup group);
 Boolean is_valid_class_object(jclass klass);

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_internal.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_internal.cpp?view=diff&rev=563554&r1=563553&r2=563554
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_internal.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_internal.cpp Tue Aug  7 10:01:41
2007
@@ -59,6 +59,11 @@
     return result;
 }
 
+Boolean is_valid_throwable_object(jobject exc)
+{
+    return is_valid_instance(exc, VM_Global_State::loader_env->java_lang_Throwable_Class);
+}
+
 Boolean is_valid_thread_object(jthread thread)
 {
     return is_valid_instance(thread, VM_Global_State::loader_env->java_lang_Thread_Class);

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_thread.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_thread.cpp?view=diff&rev=563554&r1=563553&r2=563554
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_thread.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_thread.cpp Tue Aug  7 10:01:41
2007
@@ -413,22 +413,17 @@
         return JVMTI_ERROR_THREAD_NOT_ALIVE;
     }
 
-    if (exception == NULL) return JVMTI_ERROR_INVALID_OBJECT;
-    tmn_suspend_disable();       //---------------------------------v
-    ObjectHandle h = (ObjectHandle)exception;
-    ManagedObject *mo = h->object;
-
-    // Check that reference pointer points to the heap
-    if (mo < (ManagedObject*)VM_Global_State::loader_env->heap_base ||
-        mo > (ManagedObject*)VM_Global_State::loader_env->heap_end)
-    {
-        tmn_suspend_enable();
+    if (! is_valid_throwable_object(exception))
         return JVMTI_ERROR_INVALID_OBJECT;
-    }
 
-    tmn_suspend_enable();       //---------------------------------^
 
-    return (jvmtiError)jthread_exception_stop(thread, exception);
+    if (TM_ERROR_NONE != jthread_exception_stop(thread, exception))
+        return JVMTI_ERROR_INTERNAL;
+
+    // force exit from wait
+    jthread_interrupt(thread);
+
+    return JVMTI_ERROR_NONE;
 }
 
 /*



Mime
View raw message