Merge "Remove support for generating .eh_frame ELF section."
diff --git a/Android.mk b/Android.mk
index a98bedc..e4cc5c0 100644
--- a/Android.mk
+++ b/Android.mk
@@ -487,14 +487,28 @@
lib/bootstrap/libdl.so \
lib64/bootstrap/libc.so \
lib64/bootstrap/libm.so \
- lib64/bootstrap/libdl.so
+ lib64/bootstrap/libdl.so \
-.PHONY: art-bionic-files
-art-bionic-files: libc.bootstrap libdl.bootstrap libm.bootstrap linker
+PRIVATE_RUNTIME_DEPENDENCY_LIBS := \
+ lib/libnativebridge.so \
+ lib64/libnativebridge.so \
+ lib/libnativehelper.so \
+ lib64/libnativehelper.so \
+ lib/libdexfile_external.so \
+ lib64/libdexfile_external.so \
+ lib/libnativeloader.so \
+ lib64/libnativeloader.so \
+
+.PHONY: standalone-apex-files
+standalone-apex-files: libc.bootstrap libdl.bootstrap libm.bootstrap linker com.android.runtime.debug
for f in $(PRIVATE_BIONIC_FILES); do \
tf=$(TARGET_OUT)/$$f; \
if [ -f $$tf ]; then cp -f $$tf $$(echo $$tf | sed 's,bootstrap/,,'); fi; \
done
+ for f in $(PRIVATE_RUNTIME_DEPENDENCY_LIBS); do \
+ tf=$(TARGET_OUT)/../apex/com.android.runtime.debug/$$f; \
+ if [ -f $$tf ]; then cp -f $$tf $(TARGET_OUT)/$$f; fi; \
+ done
########################################################################
# Phony target for only building what go/lem requires for pushing ART on /data.
@@ -529,7 +543,7 @@
$(TARGET_CORE_IMG_OUT_BASE)-interpreter.art \
libc.bootstrap libdl.bootstrap libm.bootstrap \
icu-data-art-test \
- art-bionic-files
+ standalone-apex-files
# remove debug libraries from public.libraries.txt because golem builds
# won't have it.
sed -i '/libartd.so/d' $(TARGET_OUT)/etc/public.libraries.txt
diff --git a/build/Android.common_test.mk b/build/Android.common_test.mk
index 12eae89..55b8ae2 100644
--- a/build/Android.common_test.mk
+++ b/build/Android.common_test.mk
@@ -127,7 +127,6 @@
LOCAL_MODULE_TAGS := tests
LOCAL_JAVA_LIBRARIES := $(TARGET_TEST_CORE_JARS)
LOCAL_MODULE_PATH := $(3)
- LOCAL_DEX_PREOPT_IMAGE_LOCATION := $(TARGET_CORE_IMG_OUT)
ifneq ($(wildcard $(LOCAL_PATH)/$(2)/main.list),)
LOCAL_MIN_SDK_VERSION := 19
LOCAL_DX_FLAGS := --multi-dex --main-dex-list=$(LOCAL_PATH)/$(2)/main.list --minimal-main-dex
@@ -143,7 +142,6 @@
LOCAL_DEX_PREOPT := false
LOCAL_ADDITIONAL_DEPENDENCIES := art/build/Android.common_test.mk $(4)
LOCAL_JAVA_LIBRARIES := $(HOST_TEST_CORE_JARS)
- LOCAL_DEX_PREOPT_IMAGE := $(HOST_CORE_IMG_LOCATION)
ifneq ($(wildcard $(LOCAL_PATH)/$(2)/main.list),)
LOCAL_MIN_SDK_VERSION := 19
LOCAL_DX_FLAGS := --multi-dex --main-dex-list=$(LOCAL_PATH)/$(2)/main.list --minimal-main-dex
diff --git a/build/art.go b/build/art.go
index 4b63829..4db8da2 100644
--- a/build/art.go
+++ b/build/art.go
@@ -253,8 +253,10 @@
ctx.AppendProperties(p)
}
+var testMapKey = android.NewOnceKey("artTests")
+
func testMap(config android.Config) map[string][]string {
- return config.Once("artTests", func() interface{} {
+ return config.Once(testMapKey, func() interface{} {
return make(map[string][]string)
}).(map[string][]string)
}
diff --git a/openjdkjvmti/ti_thread.cc b/openjdkjvmti/ti_thread.cc
index 051db4c..1021648 100644
--- a/openjdkjvmti/ti_thread.cc
+++ b/openjdkjvmti/ti_thread.cc
@@ -47,6 +47,7 @@
#include "mirror/class.h"
#include "mirror/object-inl.h"
#include "mirror/string.h"
+#include "mirror/throwable.h"
#include "nativehelper/scoped_local_ref.h"
#include "nativehelper/scoped_utf_chars.h"
#include "obj_ptr.h"
@@ -83,6 +84,17 @@
}
void ThreadStart(art::Thread* self) override REQUIRES_SHARED(art::Locks::mutator_lock_) {
+ // Needs to be checked first because we might start these threads before we actually send the
+ // VMInit event.
+ if (self->IsSystemDaemon()) {
+ // System daemon threads are things like the finalizer or gc thread. It would be dangerous to
+ // allow agents to get in the way of these threads starting up. These threads include things
+ // like the HeapTaskDaemon and the finalizer daemon.
+ //
+ // This event can happen during the time before VMInit or just after zygote fork. Since the
+ // second is hard to distinguish we unfortunately cannot really check the state here.
+ return;
+ }
if (!started) {
// Runtime isn't started. We only expect at most the signal handler or JIT threads to be
// started here.
@@ -132,16 +144,35 @@
gThreadCallback.Post<ArtJvmtiEvent::kThreadStart>(art::Thread::Current());
}
+
+static void WaitForSystemDaemonStart(art::Thread* self) REQUIRES_SHARED(art::Locks::mutator_lock_) {
+ {
+ art::ScopedThreadStateChange strc(self, art::kNative);
+ JNIEnv* jni = self->GetJniEnv();
+ jni->CallStaticVoidMethod(art::WellKnownClasses::java_lang_Daemons,
+ art::WellKnownClasses::java_lang_Daemons_waitForDaemonStart);
+ }
+ if (self->IsExceptionPending()) {
+ LOG(WARNING) << "Exception occured when waiting for system daemons to start: "
+ << self->GetException()->Dump();
+ self->ClearException();
+ }
+}
+
void ThreadUtil::CacheData() {
// We must have started since it is now safe to cache our data;
gThreadCallback.started = true;
- art::ScopedObjectAccess soa(art::Thread::Current());
+ art::Thread* self = art::Thread::Current();
+ art::ScopedObjectAccess soa(self);
art::ObjPtr<art::mirror::Class> thread_class =
soa.Decode<art::mirror::Class>(art::WellKnownClasses::java_lang_Thread);
CHECK(thread_class != nullptr);
context_class_loader_ = thread_class->FindDeclaredInstanceField("contextClassLoader",
"Ljava/lang/ClassLoader;");
CHECK(context_class_loader_ != nullptr);
+ // Now wait for all required system threads to come up before allowing the rest of loading to
+ // continue.
+ WaitForSystemDaemonStart(self);
}
void ThreadUtil::Unregister() {
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index 1465b14..7ecfdc7 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -869,15 +869,22 @@
GetInstructionSetString(kRuntimeISA));
}
- // Send the initialized phase event. Send it before starting daemons, as otherwise
- // sending thread events becomes complicated.
+ StartDaemonThreads();
+
+ // Make sure the environment is still clean (no lingering local refs from starting daemon
+ // threads).
+ {
+ ScopedObjectAccess soa(self);
+ self->GetJniEnv()->AssertLocalsEmpty();
+ }
+
+ // Send the initialized phase event. Send it after starting the Daemon threads so that agents
+ // cannot delay the daemon threads from starting forever.
{
ScopedObjectAccess soa(self);
callbacks_->NextRuntimePhase(RuntimePhaseCallback::RuntimePhase::kInit);
}
- StartDaemonThreads();
-
{
ScopedObjectAccess soa(self);
self->GetJniEnv()->AssertLocalsEmpty();
diff --git a/runtime/thread.cc b/runtime/thread.cc
index 4828aae..44b45cf 100644
--- a/runtime/thread.cc
+++ b/runtime/thread.cc
@@ -4258,4 +4258,12 @@
return priority;
}
+bool Thread::IsSystemDaemon() const {
+ if (GetPeer() == nullptr) {
+ return false;
+ }
+ return jni::DecodeArtField(
+ WellKnownClasses::java_lang_Thread_systemDaemon)->GetBoolean(GetPeer());
+}
+
} // namespace art
diff --git a/runtime/thread.h b/runtime/thread.h
index 7a14fd7..ec276b5 100644
--- a/runtime/thread.h
+++ b/runtime/thread.h
@@ -1230,6 +1230,8 @@
return this == jit_sensitive_thread_;
}
+ bool IsSystemDaemon() const REQUIRES_SHARED(Locks::mutator_lock_);
+
// Returns true if StrictMode events are traced for the current thread.
static bool IsSensitiveThread() {
if (is_sensitive_thread_hook_ != nullptr) {
diff --git a/runtime/well_known_classes.cc b/runtime/well_known_classes.cc
index 955a455..19fbf63 100644
--- a/runtime/well_known_classes.cc
+++ b/runtime/well_known_classes.cc
@@ -92,6 +92,7 @@
jmethodID WellKnownClasses::java_lang_ClassNotFoundException_init;
jmethodID WellKnownClasses::java_lang_Daemons_start;
jmethodID WellKnownClasses::java_lang_Daemons_stop;
+jmethodID WellKnownClasses::java_lang_Daemons_waitForDaemonStart;
jmethodID WellKnownClasses::java_lang_Double_valueOf;
jmethodID WellKnownClasses::java_lang_Float_valueOf;
jmethodID WellKnownClasses::java_lang_Integer_valueOf;
@@ -132,6 +133,7 @@
jfieldID WellKnownClasses::java_lang_Thread_name;
jfieldID WellKnownClasses::java_lang_Thread_priority;
jfieldID WellKnownClasses::java_lang_Thread_nativePeer;
+jfieldID WellKnownClasses::java_lang_Thread_systemDaemon;
jfieldID WellKnownClasses::java_lang_Thread_unparkedBeforeStart;
jfieldID WellKnownClasses::java_lang_ThreadGroup_groups;
jfieldID WellKnownClasses::java_lang_ThreadGroup_ngroups;
@@ -351,6 +353,7 @@
java_lang_Daemons_start = CacheMethod(env, java_lang_Daemons, true, "start", "()V");
java_lang_Daemons_stop = CacheMethod(env, java_lang_Daemons, true, "stop", "()V");
+ java_lang_Daemons_waitForDaemonStart = CacheMethod(env, java_lang_Daemons, true, "waitForDaemonStart", "()V");
java_lang_invoke_MethodHandles_lookup = CacheMethod(env, "java/lang/invoke/MethodHandles", true, "lookup", "()Ljava/lang/invoke/MethodHandles$Lookup;");
java_lang_invoke_MethodHandles_Lookup_findConstructor = CacheMethod(env, "java/lang/invoke/MethodHandles$Lookup", false, "findConstructor", "(Ljava/lang/Class;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/MethodHandle;");
@@ -385,6 +388,7 @@
java_lang_Thread_name = CacheField(env, java_lang_Thread, false, "name", "Ljava/lang/String;");
java_lang_Thread_priority = CacheField(env, java_lang_Thread, false, "priority", "I");
java_lang_Thread_nativePeer = CacheField(env, java_lang_Thread, false, "nativePeer", "J");
+ java_lang_Thread_systemDaemon = CacheField(env, java_lang_Thread, false, "systemDaemon", "Z");
java_lang_Thread_unparkedBeforeStart = CacheField(env, java_lang_Thread, false, "unparkedBeforeStart", "Z");
java_lang_ThreadGroup_groups = CacheField(env, java_lang_ThreadGroup, false, "groups", "[Ljava/lang/ThreadGroup;");
java_lang_ThreadGroup_ngroups = CacheField(env, java_lang_ThreadGroup, false, "ngroups", "I");
diff --git a/runtime/well_known_classes.h b/runtime/well_known_classes.h
index 872b562..3c5144f 100644
--- a/runtime/well_known_classes.h
+++ b/runtime/well_known_classes.h
@@ -101,6 +101,7 @@
static jmethodID java_lang_ClassNotFoundException_init;
static jmethodID java_lang_Daemons_start;
static jmethodID java_lang_Daemons_stop;
+ static jmethodID java_lang_Daemons_waitForDaemonStart;
static jmethodID java_lang_Double_valueOf;
static jmethodID java_lang_Float_valueOf;
static jmethodID java_lang_Integer_valueOf;
@@ -141,6 +142,7 @@
static jfieldID java_lang_Thread_name;
static jfieldID java_lang_Thread_priority;
static jfieldID java_lang_Thread_nativePeer;
+ static jfieldID java_lang_Thread_systemDaemon;
static jfieldID java_lang_Thread_unparkedBeforeStart;
static jfieldID java_lang_ThreadGroup_groups;
static jfieldID java_lang_ThreadGroup_ngroups;
diff --git a/test/Android.bp b/test/Android.bp
index 467a717..d070d76 100644
--- a/test/Android.bp
+++ b/test/Android.bp
@@ -540,6 +540,6 @@
"art_debug_defaults",
"art_defaults",
],
- header_libs: ["libnativebridge-dummy-headers"],
+ header_libs: ["libnativebridge-headers"],
srcs: ["115-native-bridge/nativebridge.cc"],
}
diff --git a/test/etc/run-test-jar b/test/etc/run-test-jar
index 2910920..9d79a0b 100755
--- a/test/etc/run-test-jar
+++ b/test/etc/run-test-jar
@@ -30,7 +30,8 @@
ANDROID_FLAGS=""
GDB=""
GDB_ARGS=""
-GDB_SERVER="gdbserver"
+GDBSERVER_DEVICE="gdbserver"
+GDBSERVER_HOST="gdbserver"
HAVE_IMAGE="y"
HOST="n"
BIONIC="n"
@@ -60,6 +61,8 @@
TIME_OUT_VALUE=1200 # 20 minutes.
fi
USE_GDB="n"
+USE_GDBSERVER="n"
+GDBSERVER_PORT=":5039"
USE_JVM="n"
USE_JVMTI="n"
VERIFY="y" # y=yes,n=no,s=softfail
@@ -267,6 +270,23 @@
DEBUGGER="y"
TIME_OUT="n"
shift
+ elif [ "x$1" = "x--gdbserver-port" ]; then
+ shift
+ GDBSERVER_PORT=$1
+ shift
+ elif [ "x$1" = "x--gdbserver-bin" ]; then
+ shift
+ GDBSERVER_HOST=$1
+ GDBSERVER_DEVICE=$1
+ shift
+ elif [ "x$1" = "x--gdbserver" ]; then
+ USE_GDBSERVER="y"
+ DEV_MODE="y"
+ TIME_OUT="n"
+ HOST="y"
+ ANDROID_ROOT="${ANDROID_HOST_OUT}"
+ ANDROID_RUNTIME_ROOT="${ANDROID_HOST_OUT}/com.android.runtime"
+ shift
elif [ "x$1" = "x--gdb" ]; then
USE_GDB="y"
DEV_MODE="y"
@@ -342,7 +362,7 @@
break
elif [ "x$1" = "x--64" ]; then
ISA="x86_64"
- GDB_SERVER="gdbserver64"
+ GDBSERVER_DEVICE="gdbserver64"
DALVIKVM="dalvikvm64"
LIBRARY_DIRECTORY="lib64"
TEST_DIRECTORY="nativetest64"
@@ -611,8 +631,11 @@
if [ "$USE_GDB" = "y" ]; then
- if [ "$HOST" = "n" ]; then
- GDB="$GDB_SERVER :5039"
+ if [ "$USE_GDBSERVER" = "y" ]; then
+ echo "Cannot pass both --gdb and --gdbserver at the same time!" >&2
+ exit 1
+ elif [ "$HOST" = "n" ]; then
+ GDB="$GDBSERVER_DEVICE $GDBSERVER_PORT"
else
if [ `uname` = "Darwin" ]; then
GDB=lldb
@@ -625,6 +648,12 @@
# gdbargs="--annotate=3 $gdbargs"
fi
fi
+elif [ "$USE_GDBSERVER" = "y" ]; then
+ if [ "$HOST" = "n" ]; then
+ echo "Cannot use --gdbserver in non-host configs" >&2
+ exit 1
+ fi
+ GDB="$GDBSERVER_HOST $GDBSERVER_PORT"
fi
if [ "$INTERPRETER" = "y" ]; then
@@ -1084,7 +1113,10 @@
if [ "$USE_GDB" = "y" ]; then
# When running under gdb, we cannot do piping and grepping...
- echo "Run 'gdbclient.py -p <pid printed below>' to debug."
+ $cmdline "$@"
+ elif [ "$USE_GDBSERVER" = "y" ]; then
+ echo "Connect to $GDBSERVER_PORT"
+ # When running under gdb, we cannot do piping and grepping...
$cmdline "$@"
else
if [ "$TIME_OUT" != "gdb" ]; then
diff --git a/test/run-test b/test/run-test
index 67bcce7..5f78d17 100755
--- a/test/run-test
+++ b/test/run-test
@@ -306,6 +306,18 @@
run_args="${run_args} --gdb"
dev_mode="yes"
shift
+ elif [ "x$1" = "x--gdbserver-bin" ]; then
+ shift
+ run_args="${run_args} --gdbserver-bin $1"
+ shift
+ elif [ "x$1" = "x--gdbserver-port" ]; then
+ shift
+ run_args="${run_args} --gdbserver-port $1"
+ shift
+ elif [ "x$1" = "x--gdbserver" ]; then
+ run_args="${run_args} --gdbserver"
+ dev_mode="yes"
+ shift
elif [ "x$1" = "x--strace" ]; then
strace="yes"
run_args="${run_args} --timeout 1800 --invoke-with strace --invoke-with -o --invoke-with $tmp_dir/$strace_output"
@@ -716,7 +728,12 @@
echo " --with-agent <agent> Run the test with the given agent loaded with -agentpath:"
echo " --debuggable Whether to compile Java code for a debugger."
echo " --gdb Run under gdb; incompatible with some tests."
- echo " --gdb-arg Pass an option to gdb."
+ echo " --gdbserver Start gdbserver (defaults to port :5039)."
+ echo " --gdbserver-port <port>"
+ echo " Start gdbserver with the given COMM (see man gdbserver)."
+ echo " --gdbserver-bin <binary>"
+ echo " Use the given binary as gdbserver."
+ echo " --gdb-arg Pass an option to gdb or gdbserver."
echo " --build-only Build test files only (off by default)."
echo " --interpreter Enable interpreter only mode (off by default)."
echo " --jit Enable jit (off by default)."
diff --git a/tools/buildbot-build.sh b/tools/buildbot-build.sh
index 6be243a..e63e6f1 100755
--- a/tools/buildbot-build.sh
+++ b/tools/buildbot-build.sh
@@ -77,7 +77,7 @@
make_command+=" debuggerd su"
make_command+=" libstdc++ "
make_command+=" ${ANDROID_PRODUCT_OUT#"${ANDROID_BUILD_TOP}/"}/system/etc/public.libraries.txt"
- make_command+=" art-bionic-files"
+ make_command+=" standalone-apex-files"
if [[ -n "$ART_TEST_CHROOT" ]]; then
# These targets are needed for the chroot environment.
make_command+=" crash_dump event-log-tags"