diff options
author | 2017-09-29 21:38:44 +0000 | |
---|---|---|
committer | 2017-09-29 21:38:44 +0000 | |
commit | f67f115423c9ef5aa62a33c12670cd8f89457c9c (patch) | |
tree | 9381a1f2a0d5d8c7a52bcbce3c09c819177972a3 | |
parent | 2cda354d7fcd4e0a32462d4aaa448869a93b20a3 (diff) | |
parent | df13240f4b9325b34d09e20cdac4e9a0b12ead61 (diff) |
Merge "Send ThreadEnd after clearing ThreadGroup."
20 files changed, 517 insertions, 2 deletions
diff --git a/runtime/thread.cc b/runtime/thread.cc index b66365a1a9..524e73d937 100644 --- a/runtime/thread.cc +++ b/runtime/thread.cc @@ -2159,11 +2159,11 @@ void Thread::Destroy() { ScopedObjectAccess soa(self); // We may need to call user-supplied managed code, do this before final clean-up. HandleUncaughtExceptions(soa); + RemoveFromThreadGroup(soa); Runtime* runtime = Runtime::Current(); if (runtime != nullptr) { runtime->GetRuntimeCallbacks()->ThreadDeath(self); } - RemoveFromThreadGroup(soa); // this.nativePeer = 0; if (Runtime::Current()->IsActiveTransaction()) { diff --git a/test/1923-frame-pop/src/art/Trace.java b/test/1923-frame-pop/src/art/Trace.java index ba3d397b0b..8999bb1368 100644 --- a/test/1923-frame-pop/src/art/Trace.java +++ b/test/1923-frame-pop/src/art/Trace.java @@ -53,4 +53,16 @@ public class Trace { public static native void watchFieldModification(Field f); public static native void watchAllFieldAccesses(); public static native void watchAllFieldModifications(); + + // the names, arguments, and even line numbers of these functions are embedded in the tests so we + // need to add to the bottom and not modify old ones to maintain compat. + public static native void enableTracing2(Class<?> methodClass, + Method entryMethod, + Method exitMethod, + Method fieldAccess, + Method fieldModify, + Method singleStep, + Method ThreadStart, + Method ThreadEnd, + Thread thr); } diff --git a/test/1924-frame-pop-toggle/src/art/Trace.java b/test/1924-frame-pop-toggle/src/art/Trace.java index ba3d397b0b..8999bb1368 100644 --- a/test/1924-frame-pop-toggle/src/art/Trace.java +++ b/test/1924-frame-pop-toggle/src/art/Trace.java @@ -53,4 +53,16 @@ public class Trace { public static native void watchFieldModification(Field f); public static native void watchAllFieldAccesses(); public static native void watchAllFieldModifications(); + + // the names, arguments, and even line numbers of these functions are embedded in the tests so we + // need to add to the bottom and not modify old ones to maintain compat. + public static native void enableTracing2(Class<?> methodClass, + Method entryMethod, + Method exitMethod, + Method fieldAccess, + Method fieldModify, + Method singleStep, + Method ThreadStart, + Method ThreadEnd, + Thread thr); } diff --git a/test/1925-self-frame-pop/src/art/Trace.java b/test/1925-self-frame-pop/src/art/Trace.java index ba3d397b0b..8999bb1368 100644 --- a/test/1925-self-frame-pop/src/art/Trace.java +++ b/test/1925-self-frame-pop/src/art/Trace.java @@ -53,4 +53,16 @@ public class Trace { public static native void watchFieldModification(Field f); public static native void watchAllFieldAccesses(); public static native void watchAllFieldModifications(); + + // the names, arguments, and even line numbers of these functions are embedded in the tests so we + // need to add to the bottom and not modify old ones to maintain compat. + public static native void enableTracing2(Class<?> methodClass, + Method entryMethod, + Method exitMethod, + Method fieldAccess, + Method fieldModify, + Method singleStep, + Method ThreadStart, + Method ThreadEnd, + Thread thr); } diff --git a/test/1926-missed-frame-pop/src/art/Trace.java b/test/1926-missed-frame-pop/src/art/Trace.java index ba3d397b0b..8999bb1368 100644 --- a/test/1926-missed-frame-pop/src/art/Trace.java +++ b/test/1926-missed-frame-pop/src/art/Trace.java @@ -53,4 +53,16 @@ public class Trace { public static native void watchFieldModification(Field f); public static native void watchAllFieldAccesses(); public static native void watchAllFieldModifications(); + + // the names, arguments, and even line numbers of these functions are embedded in the tests so we + // need to add to the bottom and not modify old ones to maintain compat. + public static native void enableTracing2(Class<?> methodClass, + Method entryMethod, + Method exitMethod, + Method fieldAccess, + Method fieldModify, + Method singleStep, + Method ThreadStart, + Method ThreadEnd, + Thread thr); } diff --git a/test/1936-thread-end-events/check b/test/1936-thread-end-events/check new file mode 100644 index 0000000000..8a84388a8f --- /dev/null +++ b/test/1936-thread-end-events/check @@ -0,0 +1,22 @@ +#!/bin/bash +# +# Copyright (C) 2017 The Android Open Source Project +# +# Licensed 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. + +# The RI sends an extra event that art doesn't. Add it to the expected output. +if [[ "$TEST_RUNTIME" == "jvm" ]]; then + patch -p0 expected.txt < jvm-expected.patch >/dev/null +fi + +./default-check "$@" diff --git a/test/1936-thread-end-events/expected.txt b/test/1936-thread-end-events/expected.txt new file mode 100644 index 0000000000..6b71c5e2c5 --- /dev/null +++ b/test/1936-thread-end-events/expected.txt @@ -0,0 +1,42 @@ +Entered public static void art.Test1936.foo() +Thread: test-thread + | alive: true + | interrupted: false + | daemon: false + | group: java.lang.ThreadGroup[name=main,maxpri=10] + +Entered void java.lang.ThreadGroup.threadTerminated(java.lang.Thread) +Thread: test-thread + | alive: true + | interrupted: false + | daemon: false + | group: java.lang.ThreadGroup[name=main,maxpri=10] + +Entered private void java.lang.ThreadGroup.remove(java.lang.Thread) +Thread: test-thread + | alive: true + | interrupted: false + | daemon: false + | group: java.lang.ThreadGroup[name=main,maxpri=10] + +Entered public static native void java.lang.System.arraycopy(java.lang.Object,int,java.lang.Object,int,int) +Thread: test-thread + | alive: true + | interrupted: false + | daemon: false + | group: java.lang.ThreadGroup[name=main,maxpri=10] + +Entered public static void art.Test1936.NotifyThreadEnd(java.lang.Thread) +Thread: test-thread + | alive: true + | interrupted: false + | daemon: false + | group: java.lang.ThreadGroup[name=main,maxpri=10] + +Entered public static void art.Test1936.foo() +Thread: test-thread + | alive: true + | interrupted: false + | daemon: false + | group: java.lang.ThreadGroup[name=main,maxpri=10] + diff --git a/test/1936-thread-end-events/info.txt b/test/1936-thread-end-events/info.txt new file mode 100644 index 0000000000..51986c4512 --- /dev/null +++ b/test/1936-thread-end-events/info.txt @@ -0,0 +1,6 @@ +Tests JVMTI ThreadEnd bug + +We had a bug where we were still sending events after JVMTI_EVENT_THREAD_END due +to where we sent the event. This test ensures that the placement of the +THREAD_END event is correct. + diff --git a/test/1936-thread-end-events/jvm-expected.patch b/test/1936-thread-end-events/jvm-expected.patch new file mode 100644 index 0000000000..ddb30a326c --- /dev/null +++ b/test/1936-thread-end-events/jvm-expected.patch @@ -0,0 +1,16 @@ +7a8,14 +> Entered private void java.lang.Thread.exit() +> Thread: test-thread +> | alive: true +> | interrupted: false +> | daemon: false +> | group: java.lang.ThreadGroup[name=main,maxpri=10] +> +34c41 +< | group: java.lang.ThreadGroup[name=main,maxpri=10] +--- +> | group: null +41c48 +< | group: java.lang.ThreadGroup[name=main,maxpri=10] +--- +> | group: null diff --git a/test/1936-thread-end-events/method_trace.cc b/test/1936-thread-end-events/method_trace.cc new file mode 100644 index 0000000000..019b6a9a24 --- /dev/null +++ b/test/1936-thread-end-events/method_trace.cc @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed 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. + */ + +#include <inttypes.h> + +#include <cstdio> +#include <memory> + +#include "android-base/logging.h" +#include "android-base/stringprintf.h" + +#include "jni.h" +#include "jvmti.h" +#include "scoped_local_ref.h" + +// Test infrastructure +#include "jni_binder.h" +#include "jni_helper.h" +#include "jvmti_helper.h" +#include "test_env.h" +#include "ti_macros.h" + +namespace art { +namespace Test989StackTraceThrow { + +extern "C" JNIEXPORT +jfloat JNICALL Java_art_Test989_returnFloatNative(JNIEnv* env, jclass klass) { + jmethodID targetMethod = env->GetStaticMethodID(klass, "doGetFloat", "()F"); + return env->CallStaticFloatMethod(klass, targetMethod); +} +extern "C" JNIEXPORT +jdouble JNICALL Java_art_Test989_returnDoubleNative(JNIEnv* env, jclass klass) { + jmethodID targetMethod = env->GetStaticMethodID(klass, "doGetDouble", "()D"); + return env->CallStaticDoubleMethod(klass, targetMethod); +} + +extern "C" JNIEXPORT jobject JNICALL Java_art_Test989_returnValueNative(JNIEnv* env, jclass klass) { + jmethodID targetMethod = env->GetStaticMethodID(klass, "mkTestObject", "()Ljava/lang/Object;"); + return env->CallStaticObjectMethod(klass, targetMethod); +} + +extern "C" JNIEXPORT void JNICALL Java_art_Test989_doNothingNative(JNIEnv* env ATTRIBUTE_UNUSED, + jclass klass ATTRIBUTE_UNUSED) { + return; +} + +extern "C" JNIEXPORT void JNICALL Java_art_Test989_throwANative(JNIEnv* env, + jclass klass) { + jmethodID targetMethod = env->GetStaticMethodID(klass, "doThrowA", "()V"); + env->CallStaticVoidMethod(klass, targetMethod); +} + +extern "C" JNIEXPORT void JNICALL Java_art_Test989_acceptValueNative(JNIEnv* env, + jclass klass, + jobject arg) { + jmethodID targetMethod = env->GetStaticMethodID(klass, "printObject", "(Ljava/lang/Object;)V"); + env->CallStaticVoidMethod(klass, targetMethod, arg); +} + +} // namespace Test989StackTraceThrow +} // namespace art + diff --git a/test/1936-thread-end-events/run b/test/1936-thread-end-events/run new file mode 100755 index 0000000000..51875a7e86 --- /dev/null +++ b/test/1936-thread-end-events/run @@ -0,0 +1,18 @@ +#!/bin/bash +# +# Copyright 2017 The Android Open Source Project +# +# Licensed 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. + +# Ask for stack traces to be dumped to a file rather than to stdout. +./default-run "$@" --jvmti diff --git a/test/1936-thread-end-events/src/Main.java b/test/1936-thread-end-events/src/Main.java new file mode 100644 index 0000000000..da66fc322c --- /dev/null +++ b/test/1936-thread-end-events/src/Main.java @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed 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. + */ + +public class Main { + public static void main(String[] args) throws Exception { + art.Test1936.run(); + } +} diff --git a/test/1936-thread-end-events/src/art/Test1936.java b/test/1936-thread-end-events/src/art/Test1936.java new file mode 100644 index 0000000000..868decad52 --- /dev/null +++ b/test/1936-thread-end-events/src/art/Test1936.java @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed 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. + */ + +package art; + +public class Test1936 { + public static void foo() {} + + public static void NotifyThreadEnd(Thread me) { + // Don't actually do anything. + foo(); + } + + public static void NotifyMethodEntry(Object o) { + System.out.println("Entered " + o.toString()); + Thread me = Thread.currentThread(); + System.out.println(String.format( + "Thread: %s\n" + + " | alive: %b\n" + + " | interrupted: %b\n" + + " | daemon: %b\n" + + " | group: %s\n", + me.getName(), me.isAlive(), me.isInterrupted(), me.isDaemon(), me.getThreadGroup())); + } + + public static native void waitForever(); + private static void setupTracing(Thread target) throws Exception { + Trace.disableTracing(target); + Trace.enableTracing2( + Test1936.class, + Test1936.class.getDeclaredMethod("NotifyMethodEntry", Object.class), + /*exit*/null, + /*field_access*/null, + /*field_modify*/null, + /*single_step*/null, + /*thread_start*/null, + Test1936.class.getDeclaredMethod("NotifyThreadEnd", Thread.class), + target); + } + + + public static void run() throws Exception { + Thread t = new Thread(() -> { + try { + setupTracing(Thread.currentThread()); + foo(); + } catch (Exception e) { + System.out.println("Caught exception " + e + "!"); + e.printStackTrace(); + } + }, "test-thread"); + t.start(); + t.join(); + } +} diff --git a/test/1936-thread-end-events/src/art/Trace.java b/test/1936-thread-end-events/src/art/Trace.java new file mode 100644 index 0000000000..8999bb1368 --- /dev/null +++ b/test/1936-thread-end-events/src/art/Trace.java @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed 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. + */ + +package art; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; + +public class Trace { + public static native void enableTracing(Class<?> methodClass, + Method entryMethod, + Method exitMethod, + Method fieldAccess, + Method fieldModify, + Method singleStep, + Thread thr); + public static native void disableTracing(Thread thr); + + public static void enableFieldTracing(Class<?> methodClass, + Method fieldAccess, + Method fieldModify, + Thread thr) { + enableTracing(methodClass, null, null, fieldAccess, fieldModify, null, thr); + } + + public static void enableMethodTracing(Class<?> methodClass, + Method entryMethod, + Method exitMethod, + Thread thr) { + enableTracing(methodClass, entryMethod, exitMethod, null, null, null, thr); + } + + public static void enableSingleStepTracing(Class<?> methodClass, + Method singleStep, + Thread thr) { + enableTracing(methodClass, null, null, null, null, singleStep, thr); + } + + public static native void watchFieldAccess(Field f); + public static native void watchFieldModification(Field f); + public static native void watchAllFieldAccesses(); + public static native void watchAllFieldModifications(); + + // the names, arguments, and even line numbers of these functions are embedded in the tests so we + // need to add to the bottom and not modify old ones to maintain compat. + public static native void enableTracing2(Class<?> methodClass, + Method entryMethod, + Method exitMethod, + Method fieldAccess, + Method fieldModify, + Method singleStep, + Method ThreadStart, + Method ThreadEnd, + Thread thr); +} diff --git a/test/988-method-trace/src/art/Trace.java b/test/988-method-trace/src/art/Trace.java index ba3d397b0b..8999bb1368 100644 --- a/test/988-method-trace/src/art/Trace.java +++ b/test/988-method-trace/src/art/Trace.java @@ -53,4 +53,16 @@ public class Trace { public static native void watchFieldModification(Field f); public static native void watchAllFieldAccesses(); public static native void watchAllFieldModifications(); + + // the names, arguments, and even line numbers of these functions are embedded in the tests so we + // need to add to the bottom and not modify old ones to maintain compat. + public static native void enableTracing2(Class<?> methodClass, + Method entryMethod, + Method exitMethod, + Method fieldAccess, + Method fieldModify, + Method singleStep, + Method ThreadStart, + Method ThreadEnd, + Thread thr); } diff --git a/test/989-method-trace-throw/src/art/Trace.java b/test/989-method-trace-throw/src/art/Trace.java index ba3d397b0b..8999bb1368 100644 --- a/test/989-method-trace-throw/src/art/Trace.java +++ b/test/989-method-trace-throw/src/art/Trace.java @@ -53,4 +53,16 @@ public class Trace { public static native void watchFieldModification(Field f); public static native void watchAllFieldAccesses(); public static native void watchAllFieldModifications(); + + // the names, arguments, and even line numbers of these functions are embedded in the tests so we + // need to add to the bottom and not modify old ones to maintain compat. + public static native void enableTracing2(Class<?> methodClass, + Method entryMethod, + Method exitMethod, + Method fieldAccess, + Method fieldModify, + Method singleStep, + Method ThreadStart, + Method ThreadEnd, + Thread thr); } diff --git a/test/990-field-trace/src/art/Trace.java b/test/990-field-trace/src/art/Trace.java index ba3d397b0b..8999bb1368 100644 --- a/test/990-field-trace/src/art/Trace.java +++ b/test/990-field-trace/src/art/Trace.java @@ -53,4 +53,16 @@ public class Trace { public static native void watchFieldModification(Field f); public static native void watchAllFieldAccesses(); public static native void watchAllFieldModifications(); + + // the names, arguments, and even line numbers of these functions are embedded in the tests so we + // need to add to the bottom and not modify old ones to maintain compat. + public static native void enableTracing2(Class<?> methodClass, + Method entryMethod, + Method exitMethod, + Method fieldAccess, + Method fieldModify, + Method singleStep, + Method ThreadStart, + Method ThreadEnd, + Thread thr); } diff --git a/test/991-field-trace-2/src/art/Trace.java b/test/991-field-trace-2/src/art/Trace.java index ba3d397b0b..8999bb1368 100644 --- a/test/991-field-trace-2/src/art/Trace.java +++ b/test/991-field-trace-2/src/art/Trace.java @@ -53,4 +53,16 @@ public class Trace { public static native void watchFieldModification(Field f); public static native void watchAllFieldAccesses(); public static native void watchAllFieldModifications(); + + // the names, arguments, and even line numbers of these functions are embedded in the tests so we + // need to add to the bottom and not modify old ones to maintain compat. + public static native void enableTracing2(Class<?> methodClass, + Method entryMethod, + Method exitMethod, + Method fieldAccess, + Method fieldModify, + Method singleStep, + Method ThreadStart, + Method ThreadEnd, + Thread thr); } diff --git a/test/997-single-step/src/art/Trace.java b/test/997-single-step/src/art/Trace.java index ba3d397b0b..8999bb1368 100644 --- a/test/997-single-step/src/art/Trace.java +++ b/test/997-single-step/src/art/Trace.java @@ -53,4 +53,16 @@ public class Trace { public static native void watchFieldModification(Field f); public static native void watchAllFieldAccesses(); public static native void watchAllFieldModifications(); + + // the names, arguments, and even line numbers of these functions are embedded in the tests so we + // need to add to the bottom and not modify old ones to maintain compat. + public static native void enableTracing2(Class<?> methodClass, + Method entryMethod, + Method exitMethod, + Method fieldAccess, + Method fieldModify, + Method singleStep, + Method ThreadStart, + Method ThreadEnd, + Thread thr); } diff --git a/test/ti-agent/trace_helper.cc b/test/ti-agent/trace_helper.cc index 1f8ceff91c..8b74c7c089 100644 --- a/test/ti-agent/trace_helper.cc +++ b/test/ti-agent/trace_helper.cc @@ -34,11 +34,36 @@ struct TraceData { jmethodID field_access; jmethodID field_modify; jmethodID single_step; + jmethodID thread_start; + jmethodID thread_end; bool in_callback; bool access_watch_on_load; bool modify_watch_on_load; }; +static void threadStartCB(jvmtiEnv* jvmti, + JNIEnv* jnienv, + jthread thread) { + TraceData* data = nullptr; + if (JvmtiErrorToException(jnienv, jvmti, + jvmti->GetEnvironmentLocalStorage(reinterpret_cast<void**>(&data)))) { + return; + } + CHECK(data->thread_start != nullptr); + jnienv->CallStaticVoidMethod(data->test_klass, data->thread_start, thread); +} +static void threadEndCB(jvmtiEnv* jvmti, + JNIEnv* jnienv, + jthread thread) { + TraceData* data = nullptr; + if (JvmtiErrorToException(jnienv, jvmti, + jvmti->GetEnvironmentLocalStorage(reinterpret_cast<void**>(&data)))) { + return; + } + CHECK(data->thread_end != nullptr); + jnienv->CallStaticVoidMethod(data->test_klass, data->thread_end, thread); +} + static void singleStepCB(jvmtiEnv* jvmti, JNIEnv* jnienv, jthread thread, @@ -362,7 +387,7 @@ extern "C" JNIEXPORT void JNICALL Java_art_Trace_watchFieldAccess( env->DeleteLocalRef(klass); } -extern "C" JNIEXPORT void JNICALL Java_art_Trace_enableTracing( +extern "C" JNIEXPORT void JNICALL Java_art_Trace_enableTracing2( JNIEnv* env, jclass trace ATTRIBUTE_UNUSED, jclass klass, @@ -371,6 +396,8 @@ extern "C" JNIEXPORT void JNICALL Java_art_Trace_enableTracing( jobject field_access, jobject field_modify, jobject single_step, + jobject thread_start, + jobject thread_end, jthread thr) { TraceData* data = nullptr; if (JvmtiErrorToException(env, @@ -386,6 +413,8 @@ extern "C" JNIEXPORT void JNICALL Java_art_Trace_enableTracing( data->field_access = field_access != nullptr ? env->FromReflectedMethod(field_access) : nullptr; data->field_modify = field_modify != nullptr ? env->FromReflectedMethod(field_modify) : nullptr; data->single_step = single_step != nullptr ? env->FromReflectedMethod(single_step) : nullptr; + data->thread_start = thread_start != nullptr ? env->FromReflectedMethod(thread_start) : nullptr; + data->thread_end = thread_end != nullptr ? env->FromReflectedMethod(thread_end) : nullptr; data->in_callback = false; TraceData* old_data = nullptr; @@ -410,6 +439,8 @@ extern "C" JNIEXPORT void JNICALL Java_art_Trace_enableTracing( cb.FieldModification = fieldModificationCB; cb.ClassPrepare = classPrepareCB; cb.SingleStep = singleStepCB; + cb.ThreadStart = threadStartCB; + cb.ThreadEnd = threadEndCB; if (JvmtiErrorToException(env, jvmti_env, jvmti_env->SetEventCallbacks(&cb, sizeof(cb)))) { return; } @@ -453,6 +484,46 @@ extern "C" JNIEXPORT void JNICALL Java_art_Trace_enableTracing( thr))) { return; } + if (thread_start != nullptr && + JvmtiErrorToException(env, + jvmti_env, + jvmti_env->SetEventNotificationMode(JVMTI_ENABLE, + JVMTI_EVENT_THREAD_START, + thr))) { + return; + } + if (thread_end != nullptr && + JvmtiErrorToException(env, + jvmti_env, + jvmti_env->SetEventNotificationMode(JVMTI_ENABLE, + JVMTI_EVENT_THREAD_END, + thr))) { + return; + } +} + +extern "C" JNIEXPORT void JNICALL Java_art_Trace_enableTracing( + JNIEnv* env, + jclass trace, + jclass klass, + jobject enter, + jobject exit, + jobject field_access, + jobject field_modify, + jobject single_step, + jthread thr) { + Java_art_Trace_enableTracing2(env, + trace, + klass, + enter, + exit, + field_access, + field_modify, + single_step, + /* thread_start */ nullptr, + /* thread_end */ nullptr, + thr); + return; } extern "C" JNIEXPORT void JNICALL Java_art_Trace_disableTracing( |