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"