Merge "Newer kernels added SEGV_BNDERR."
diff --git a/crash_reporter/Android.mk b/crash_reporter/Android.mk
index fa564b2..ce9dc73 100644
--- a/crash_reporter/Android.mk
+++ b/crash_reporter/Android.mk
@@ -136,7 +136,7 @@
 LOCAL_MODULE := crash_reporter_tests
 LOCAL_CPP_EXTENSION := $(crash_reporter_cpp_extension)
 ifdef BRILLO
-LOCAL_MODULE_TAGS := debug
+LOCAL_MODULE_TAGS := eng
 endif
 LOCAL_SHARED_LIBRARIES := libchrome \
     libbrillo \
diff --git a/libcutils/str_parms.c b/libcutils/str_parms.c
index 4f23d09..8dafded 100644
--- a/libcutils/str_parms.c
+++ b/libcutils/str_parms.c
@@ -31,6 +31,20 @@
 
 #define UNUSED __attribute__((unused))
 
+/* When an object is allocated but not freed in a function,
+ * because its ownership is released to other object like a hashmap,
+ * call RELEASE_OWNERSHIP to tell the clang analyzer and avoid
+ * false warnings about potential memory leak.
+ * For now, a "temporary" assignment to global variables
+ * is enough to confuse the clang static analyzer.
+ */
+#ifdef __clang_analyzer__
+static void *released_pointer;
+#define RELEASE_OWNERSHIP(x) { released_pointer = x; released_pointer = 0; }
+#else
+#define RELEASE_OWNERSHIP(x)
+#endif
+
 struct str_parms {
     Hashmap *map;
 };
@@ -170,9 +184,12 @@
 
         /* if we replaced a value, free it */
         old_val = hashmapPut(str_parms->map, key, value);
+        RELEASE_OWNERSHIP(value);
         if (old_val) {
             free(old_val);
             free(key);
+        } else {
+            RELEASE_OWNERSHIP(key);
         }
 
         items++;
@@ -222,10 +239,13 @@
             goto clean_up;
         }
         // For new keys, hashmap takes ownership of tmp_key and tmp_val.
+        RELEASE_OWNERSHIP(tmp_key);
+        RELEASE_OWNERSHIP(tmp_val);
         tmp_key = tmp_val = NULL;
     } else {
         // For existing keys, hashmap takes ownership of tmp_val.
         // (It also gives up ownership of old_val.)
+        RELEASE_OWNERSHIP(tmp_val);
         tmp_val = NULL;
     }
 
diff --git a/logcat/Android.mk b/logcat/Android.mk
index c4a9550..b828a9f 100644
--- a/logcat/Android.mk
+++ b/logcat/Android.mk
@@ -11,8 +11,6 @@
 
 LOCAL_CFLAGS := -Werror
 
-LOCAL_INIT_RC := logcatd.rc
-
 include $(BUILD_EXECUTABLE)
 
 include $(CLEAR_VARS)
@@ -20,6 +18,7 @@
 LOCAL_MODULE := logpersist.start
 LOCAL_MODULE_TAGS := debug
 LOCAL_MODULE_CLASS := EXECUTABLES
+LOCAL_INIT_RC := logcatd.rc
 LOCAL_MODULE_PATH := $(bin_dir)
 LOCAL_SRC_FILES := logpersist
 ALL_TOOLS := logpersist.start logpersist.stop logpersist.cat
diff --git a/metricsd/Android.mk b/metricsd/Android.mk
index e140c62..bb262b4 100644
--- a/metricsd/Android.mk
+++ b/metricsd/Android.mk
@@ -200,7 +200,7 @@
 LOCAL_SRC_FILES := $(metricsd_tests_sources) $(metricsd_common)
 LOCAL_STATIC_LIBRARIES := libBionicGtestMain libgmock metricsd_protos metricsd_binder_proxy
 ifdef BRILLO
-LOCAL_MODULE_TAGS := debug
+LOCAL_MODULE_TAGS := eng
 endif
 include $(BUILD_NATIVE_TEST)
 
@@ -218,7 +218,7 @@
 LOCAL_STATIC_LIBRARIES := libBionicGtestMain libgmock metricsd_binder_proxy \
   $(metrics_collector_static_libraries)
 ifdef BRILLO
-LOCAL_MODULE_TAGS := debug
+LOCAL_MODULE_TAGS := eng
 endif
 include $(BUILD_NATIVE_TEST)
 
diff --git a/metricsd/uploader/metricsd_service_runner.cc b/metricsd/uploader/metricsd_service_runner.cc
index 5a759d3..4361cac 100644
--- a/metricsd/uploader/metricsd_service_runner.cc
+++ b/metricsd/uploader/metricsd_service_runner.cc
@@ -20,6 +20,7 @@
 
 #include <binder/IServiceManager.h>
 #include <brillo/binder_watcher.h>
+#include <brillo/message_loops/base_message_loop.h>
 #include <utils/Errors.h>
 
 #include "uploader/bn_metricsd_impl.h"
@@ -40,15 +41,17 @@
   CHECK(status == android::OK) << "Metricsd service registration failed";
 
   message_loop_for_io_.reset(new base::MessageLoopForIO);
+  message_loop_.reset(new brillo::BaseMessageLoop(message_loop_for_io_.get()));
 
-  brillo::BinderWatcher watcher;
+  brillo::BinderWatcher watcher(message_loop_.get());
   CHECK(watcher.Init()) << "failed to initialize the binder file descriptor "
                         << "watcher";
 
-  message_loop_for_io_->Run();
+  message_loop_->Run();
 
   // Delete the message loop here as it needs to be deconstructed in the thread
   // it is attached to.
+  message_loop_.reset();
   message_loop_for_io_.reset();
 }
 
diff --git a/metricsd/uploader/metricsd_service_runner.h b/metricsd/uploader/metricsd_service_runner.h
index 1715de0..f5dad21 100644
--- a/metricsd/uploader/metricsd_service_runner.h
+++ b/metricsd/uploader/metricsd_service_runner.h
@@ -21,6 +21,7 @@
 #include <thread>
 
 #include <base/message_loop/message_loop.h>
+#include <brillo/message_loops/message_loop.h>
 
 #include "uploader/crash_counters.h"
 
@@ -39,6 +40,7 @@
   void Run();
 
   std::unique_ptr<base::MessageLoopForIO> message_loop_for_io_;
+  std::unique_ptr<brillo::MessageLoop> message_loop_;
 
   std::unique_ptr<std::thread> thread_;
   std::shared_ptr<CrashCounters> counters_;