Merge "fastbootd: Allow returning errors from getvar handlers."
diff --git a/base/Android.bp b/base/Android.bp
index 46a0233..3d80d97 100644
--- a/base/Android.bp
+++ b/base/Android.bp
@@ -135,7 +135,6 @@
         "strings_test.cpp",
         "test_main.cpp",
         "test_utils_test.cpp",
-        "unique_fd_test.cpp",
     ],
     target: {
         android: {
diff --git a/base/include/android-base/parsedouble.h b/base/include/android-base/parsedouble.h
index c273c61..7b1c648 100644
--- a/base/include/android-base/parsedouble.h
+++ b/base/include/android-base/parsedouble.h
@@ -24,24 +24,43 @@
 namespace android {
 namespace base {
 
-// Parse double value in the string 's' and sets 'out' to that value.
+// Parse floating value in the string 's' and sets 'out' to that value if it exists.
 // Optionally allows the caller to define a 'min' and 'max' beyond which
 // otherwise valid values will be rejected. Returns boolean success.
-static inline bool ParseDouble(const char* s, double* out,
-                               double min = std::numeric_limits<double>::lowest(),
-                               double max = std::numeric_limits<double>::max()) {
+template <typename T, T (*strtox)(const char* str, char** endptr)>
+static inline bool ParseFloatingPoint(const char* s, T* out, T min, T max) {
   errno = 0;
   char* end;
-  double result = strtod(s, &end);
+  T result = strtox(s, &end);
   if (errno != 0 || s == end || *end != '\0') {
     return false;
   }
   if (result < min || max < result) {
     return false;
   }
-  *out = result;
+  if (out != nullptr) {
+    *out = result;
+  }
   return true;
 }
 
+// Parse double value in the string 's' and sets 'out' to that value if it exists.
+// Optionally allows the caller to define a 'min' and 'max' beyond which
+// otherwise valid values will be rejected. Returns boolean success.
+static inline bool ParseDouble(const char* s, double* out,
+                               double min = std::numeric_limits<double>::lowest(),
+                               double max = std::numeric_limits<double>::max()) {
+  return ParseFloatingPoint<double, strtod>(s, out, min, max);
+}
+
+// Parse float value in the string 's' and sets 'out' to that value if it exists.
+// Optionally allows the caller to define a 'min' and 'max' beyond which
+// otherwise valid values will be rejected. Returns boolean success.
+static inline bool ParseFloat(const char* s, float* out,
+                              float min = std::numeric_limits<float>::lowest(),
+                              float max = std::numeric_limits<float>::max()) {
+  return ParseFloatingPoint<float, strtof>(s, out, min, max);
+}
+
 }  // namespace base
 }  // namespace android
diff --git a/base/include/android-base/parseint.h b/base/include/android-base/parseint.h
index bb54c99..55f1ed3 100644
--- a/base/include/android-base/parseint.h
+++ b/base/include/android-base/parseint.h
@@ -27,9 +27,9 @@
 namespace base {
 
 // Parses the unsigned decimal or hexadecimal integer in the string 's' and sets
-// 'out' to that value. Optionally allows the caller to define a 'max' beyond
-// which otherwise valid values will be rejected. Returns boolean success; 'out'
-// is untouched if parsing fails.
+// 'out' to that value if it is specified. Optionally allows the caller to define
+// a 'max' beyond which otherwise valid values will be rejected. Returns boolean
+// success; 'out' is untouched if parsing fails.
 template <typename T>
 bool ParseUint(const char* s, T* out, T max = std::numeric_limits<T>::max(),
                bool allow_suffixes = false) {
@@ -72,9 +72,9 @@
 }
 
 // Parses the signed decimal or hexadecimal integer in the string 's' and sets
-// 'out' to that value. Optionally allows the caller to define a 'min' and 'max'
-// beyond which otherwise valid values will be rejected. Returns boolean
-// success; 'out' is untouched if parsing fails.
+// 'out' to that value if it is specified. Optionally allows the caller to define
+// a 'min' and 'max' beyond which otherwise valid values will be rejected. Returns
+// boolean success; 'out' is untouched if parsing fails.
 template <typename T>
 bool ParseInt(const char* s, T* out,
               T min = std::numeric_limits<T>::min(),
diff --git a/base/parsedouble_test.cpp b/base/parsedouble_test.cpp
index 8734c42..ec3c10c 100644
--- a/base/parsedouble_test.cpp
+++ b/base/parsedouble_test.cpp
@@ -18,7 +18,7 @@
 
 #include <gtest/gtest.h>
 
-TEST(parsedouble, smoke) {
+TEST(parsedouble, double_smoke) {
   double d;
   ASSERT_FALSE(android::base::ParseDouble("", &d));
   ASSERT_FALSE(android::base::ParseDouble("x", &d));
@@ -35,4 +35,33 @@
   ASSERT_FALSE(android::base::ParseDouble("3.0", &d, -1.0, 2.0));
   ASSERT_TRUE(android::base::ParseDouble("1.0", &d, 0.0, 2.0));
   ASSERT_DOUBLE_EQ(1.0, d);
+
+  ASSERT_FALSE(android::base::ParseDouble("123.4x", nullptr));
+  ASSERT_TRUE(android::base::ParseDouble("-123.4", nullptr));
+  ASSERT_FALSE(android::base::ParseDouble("3.0", nullptr, -1.0, 2.0));
+  ASSERT_TRUE(android::base::ParseDouble("1.0", nullptr, 0.0, 2.0));
+}
+
+TEST(parsedouble, float_smoke) {
+  float f;
+  ASSERT_FALSE(android::base::ParseFloat("", &f));
+  ASSERT_FALSE(android::base::ParseFloat("x", &f));
+  ASSERT_FALSE(android::base::ParseFloat("123.4x", &f));
+
+  ASSERT_TRUE(android::base::ParseFloat("123.4", &f));
+  ASSERT_FLOAT_EQ(123.4, f);
+  ASSERT_TRUE(android::base::ParseFloat("-123.4", &f));
+  ASSERT_FLOAT_EQ(-123.4, f);
+
+  ASSERT_TRUE(android::base::ParseFloat("0", &f, 0.0));
+  ASSERT_FLOAT_EQ(0.0, f);
+  ASSERT_FALSE(android::base::ParseFloat("0", &f, 1e-9));
+  ASSERT_FALSE(android::base::ParseFloat("3.0", &f, -1.0, 2.0));
+  ASSERT_TRUE(android::base::ParseFloat("1.0", &f, 0.0, 2.0));
+  ASSERT_FLOAT_EQ(1.0, f);
+
+  ASSERT_FALSE(android::base::ParseFloat("123.4x", nullptr));
+  ASSERT_TRUE(android::base::ParseFloat("-123.4", nullptr));
+  ASSERT_FALSE(android::base::ParseFloat("3.0", nullptr, -1.0, 2.0));
+  ASSERT_TRUE(android::base::ParseFloat("1.0", nullptr, 0.0, 2.0));
 }
diff --git a/base/unique_fd_test.cpp b/base/unique_fd_test.cpp
deleted file mode 100644
index 3fdf12a..0000000
--- a/base/unique_fd_test.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2018 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 "android-base/unique_fd.h"
-
-#include <gtest/gtest.h>
-
-#include <errno.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-using android::base::unique_fd;
-
-TEST(unique_fd, unowned_close) {
-#if defined(__BIONIC__)
-  unique_fd fd(open("/dev/null", O_RDONLY));
-  EXPECT_DEATH(close(fd.get()), "incorrect tag");
-#endif
-}
-
-TEST(unique_fd, untag_on_release) {
-  unique_fd fd(open("/dev/null", O_RDONLY));
-  close(fd.release());
-}
-
-TEST(unique_fd, move) {
-  unique_fd fd(open("/dev/null", O_RDONLY));
-  unique_fd fd_moved = std::move(fd);
-  ASSERT_EQ(-1, fd.get());
-  ASSERT_GT(fd_moved.get(), -1);
-}
-
-TEST(unique_fd, unowned_close_after_move) {
-#if defined(__BIONIC__)
-  unique_fd fd(open("/dev/null", O_RDONLY));
-  unique_fd fd_moved = std::move(fd);
-  ASSERT_EQ(-1, fd.get());
-  ASSERT_GT(fd_moved.get(), -1);
-  EXPECT_DEATH(close(fd_moved.get()), "incorrect tag");
-#endif
-}
diff --git a/libbacktrace/include/backtrace/BacktraceMap.h b/libbacktrace/include/backtrace/BacktraceMap.h
index a9cfce4..c564271 100644
--- a/libbacktrace/include/backtrace/BacktraceMap.h
+++ b/libbacktrace/include/backtrace/BacktraceMap.h
@@ -31,6 +31,7 @@
 
 #include <deque>
 #include <iterator>
+#include <memory>
 #include <string>
 #include <vector>
 
diff --git a/libutils/CallStack.cpp b/libutils/CallStack.cpp
index bd6015e..fe6f33d 100644
--- a/libutils/CallStack.cpp
+++ b/libutils/CallStack.cpp
@@ -16,16 +16,15 @@
 
 #define LOG_TAG "CallStack"
 
-#include <utils/CallStack.h>
-
-#include <memory>
-
 #include <utils/Printer.h>
 #include <utils/Errors.h>
 #include <utils/Log.h>
 
 #include <backtrace/Backtrace.h>
 
+#define CALLSTACK_WEAK  // Don't generate weak definitions.
+#include <utils/CallStack.h>
+
 namespace android {
 
 CallStack::CallStack() {
@@ -76,4 +75,30 @@
     }
 }
 
+// The following four functions may be used via weak symbol references from libutils.
+// Clients assume that if any of these symbols are available, then deleteStack() is.
+
+#ifdef WEAKS_AVAILABLE
+
+CallStack::CallStackUPtr CallStack::getCurrentInternal(int ignoreDepth) {
+    CallStack::CallStackUPtr stack(new CallStack());
+    stack->update(ignoreDepth + 1);
+    return stack;
+}
+
+void CallStack::logStackInternal(const char* logtag, const CallStack* stack,
+                                 android_LogPriority priority) {
+    stack->log(logtag, priority);
+}
+
+String8 CallStack::stackToStringInternal(const char* prefix, const CallStack* stack) {
+    return stack->toString(prefix);
+}
+
+void CallStack::deleteStack(CallStack* stack) {
+    delete stack;
+}
+
+#endif // WEAKS_AVAILABLE
+
 }; // namespace android
diff --git a/libutils/RefBase.cpp b/libutils/RefBase.cpp
index 9074850..3f1e79a 100644
--- a/libutils/RefBase.cpp
+++ b/libutils/RefBase.cpp
@@ -17,30 +17,41 @@
 #define LOG_TAG "RefBase"
 // #define LOG_NDEBUG 0
 
+#include <memory>
+
 #include <utils/RefBase.h>
 
 #include <utils/CallStack.h>
 
+#include <utils/Mutex.h>
+
 #ifndef __unused
 #define __unused __attribute__((__unused__))
 #endif
 
-// compile with refcounting debugging enabled
-#define DEBUG_REFS                      0
+// Compile with refcounting debugging enabled.
+#define DEBUG_REFS 0
+
+// The following three are ignored unless DEBUG_REFS is set.
 
 // whether ref-tracking is enabled by default, if not, trackMe(true, false)
 // needs to be called explicitly
-#define DEBUG_REFS_ENABLED_BY_DEFAULT   0
+#define DEBUG_REFS_ENABLED_BY_DEFAULT 0
 
 // whether callstack are collected (significantly slows things down)
-#define DEBUG_REFS_CALLSTACK_ENABLED    1
+#define DEBUG_REFS_CALLSTACK_ENABLED 1
 
 // folder where stack traces are saved when DEBUG_REFS is enabled
 // this folder needs to exist and be writable
-#define DEBUG_REFS_CALLSTACK_PATH       "/data/debug"
+#define DEBUG_REFS_CALLSTACK_PATH "/data/debug"
 
 // log all reference counting operations
-#define PRINT_REFS                      0
+#define PRINT_REFS 0
+
+// Continue after logging a stack trace if ~RefBase discovers that reference
+// count has never been incremented. Normally we conspicuously crash in that
+// case.
+#define DEBUG_REFBASE_DESTRUCTION 1
 
 // ---------------------------------------------------------------------------
 
@@ -184,7 +195,7 @@
                 char inc = refs->ref >= 0 ? '+' : '-';
                 ALOGD("\t%c ID %p (ref %d):", inc, refs->id, refs->ref);
 #if DEBUG_REFS_CALLSTACK_ENABLED
-                refs->stack.log(LOG_TAG);
+                CallStack::logStack(LOG_TAG, refs->stack.get());
 #endif
                 refs = refs->next;
             }
@@ -198,14 +209,14 @@
                 char inc = refs->ref >= 0 ? '+' : '-';
                 ALOGD("\t%c ID %p (ref %d):", inc, refs->id, refs->ref);
 #if DEBUG_REFS_CALLSTACK_ENABLED
-                refs->stack.log(LOG_TAG);
+                CallStack::logStack(LOG_TAG, refs->stack.get());
 #endif
                 refs = refs->next;
             }
         }
         if (dumpStack) {
             ALOGE("above errors at:");
-            CallStack stack(LOG_TAG);
+            CallStack::logStack(LOG_TAG);
         }
     }
 
@@ -279,7 +290,7 @@
                      this);
             int rc = open(name, O_RDWR | O_CREAT | O_APPEND, 644);
             if (rc >= 0) {
-                write(rc, text.string(), text.length());
+                (void)write(rc, text.string(), text.length());
                 close(rc);
                 ALOGD("STACK TRACE for %p saved in %s", this, name);
             }
@@ -294,7 +305,7 @@
         ref_entry* next;
         const void* id;
 #if DEBUG_REFS_CALLSTACK_ENABLED
-        CallStack stack;
+        CallStack::CallStackUPtr stack;
 #endif
         int32_t ref;
     };
@@ -311,7 +322,7 @@
             ref->ref = mRef;
             ref->id = id;
 #if DEBUG_REFS_CALLSTACK_ENABLED
-            ref->stack.update(2);
+            ref->stack = CallStack::getCurrent(2);
 #endif
             ref->next = *refs;
             *refs = ref;
@@ -346,7 +357,7 @@
                 ref = ref->next;
             }
 
-            CallStack stack(LOG_TAG);
+            CallStack::logStack(LOG_TAG);
         }
     }
 
@@ -373,7 +384,7 @@
                      inc, refs->id, refs->ref);
             out->append(buf);
 #if DEBUG_REFS_CALLSTACK_ENABLED
-            out->append(refs->stack.toString("\t\t"));
+            out->append(CallStack::stackToString("\t\t", refs->stack.get()));
 #else
             out->append("\t\t(call stacks disabled)");
 #endif
@@ -700,16 +711,16 @@
         if (mRefs->mWeak.load(std::memory_order_relaxed) == 0) {
             delete mRefs;
         }
-    } else if (mRefs->mStrong.load(std::memory_order_relaxed)
-            == INITIAL_STRONG_VALUE) {
+    } else if (mRefs->mStrong.load(std::memory_order_relaxed) == INITIAL_STRONG_VALUE) {
         // We never acquired a strong reference on this object.
-        LOG_ALWAYS_FATAL_IF(mRefs->mWeak.load() != 0,
-                "RefBase: Explicit destruction with non-zero weak "
-                "reference count");
-        // TODO: Always report if we get here. Currently MediaMetadataRetriever
-        // C++ objects are inconsistently managed and sometimes get here.
-        // There may be other cases, but we believe they should all be fixed.
-        delete mRefs;
+#if DEBUG_REFBASE_DESTRUCTION
+        // Treating this as fatal is prone to causing boot loops. For debugging, it's
+        // better to treat as non-fatal.
+        ALOGD("RefBase: Explicit destruction, weak count = %d (in %p)", mRefs->mWeak.load(), this);
+        CallStack::logStack(LOG_TAG);
+#else
+        LOG_ALWAYS_FATAL("RefBase: Explicit destruction, weak count = %d", mRefs->mWeak.load());
+#endif
     }
     // For debugging purposes, clear mRefs.  Ineffective against outstanding wp's.
     const_cast<weakref_impl*&>(mRefs) = nullptr;
diff --git a/libutils/include/utils/CallStack.h b/libutils/include/utils/CallStack.h
index 0c1b875..56004fe 100644
--- a/libutils/include/utils/CallStack.h
+++ b/libutils/include/utils/CallStack.h
@@ -17,6 +17,8 @@
 #ifndef ANDROID_CALLSTACK_H
 #define ANDROID_CALLSTACK_H
 
+#include <memory>
+
 #include <android/log.h>
 #include <backtrace/backtrace_constants.h>
 #include <utils/String8.h>
@@ -25,6 +27,19 @@
 #include <stdint.h>
 #include <sys/types.h>
 
+#if !defined(__APPLE__) && !defined(_WIN32)
+# define WEAKS_AVAILABLE 1
+#endif
+#ifndef CALLSTACK_WEAK
+# ifdef WEAKS_AVAILABLE
+#   define CALLSTACK_WEAK __attribute__((weak))
+# else // !WEAKS_AVAILABLE
+#   define CALLSTACK_WEAK
+# endif // !WEAKS_AVAILABLE
+#endif // CALLSTACK_WEAK predefined
+
+#define ALWAYS_INLINE __attribute__((always_inline))
+
 namespace android {
 
 class Printer;
@@ -36,7 +51,7 @@
     CallStack();
     // Create a callstack with the current thread's stack trace.
     // Immediately dump it to logcat using the given logtag.
-    CallStack(const char* logtag, int32_t ignoreDepth=1);
+    CallStack(const char* logtag, int32_t ignoreDepth = 1);
     ~CallStack();
 
     // Reset the stack frames (same as creating an empty call stack).
@@ -44,7 +59,7 @@
 
     // Immediately collect the stack traces for the specified thread.
     // The default is to dump the stack of the current call.
-    void update(int32_t ignoreDepth=1, pid_t tid=BACKTRACE_CURRENT_THREAD);
+    void update(int32_t ignoreDepth = 1, pid_t tid = BACKTRACE_CURRENT_THREAD);
 
     // Dump a stack trace to the log using the supplied logtag.
     void log(const char* logtag,
@@ -63,7 +78,88 @@
     // Get the count of stack frames that are in this call stack.
     size_t size() const { return mFrameLines.size(); }
 
-private:
+    // DO NOT USE ANYTHING BELOW HERE. The following public members are expected
+    // to disappear again shortly, once a better replacement facility exists.
+    // The replacement facility will be incompatible!
+
+    // Debugging accesses to some basic functionality. These use weak symbols to
+    // avoid introducing a dependency on libutilscallstack. Such a dependency from
+    // libutils results in a cyclic build dependency. These routines can be called
+    // from within libutils. But if the actual library is unavailable, they do
+    // nothing.
+    //
+    // DO NOT USE THESE. They will disappear.
+    struct StackDeleter {
+#ifdef WEAKS_AVAILABLE
+        void operator()(CallStack* stack) {
+            deleteStack(stack);
+        }
+#else
+        void operator()(CallStack*) {}
+#endif
+    };
+
+    typedef std::unique_ptr<CallStack, StackDeleter> CallStackUPtr;
+
+    // Return current call stack if possible, nullptr otherwise.
+#ifdef WEAKS_AVAILABLE
+    static CallStackUPtr ALWAYS_INLINE getCurrent(int32_t ignoreDepth = 1) {
+        if (reinterpret_cast<uintptr_t>(getCurrentInternal) == 0) {
+            ALOGW("CallStack::getCurrentInternal not linked, returning null");
+            return CallStackUPtr(nullptr);
+        } else {
+            return getCurrentInternal(ignoreDepth);
+        }
+    }
+#else // !WEAKS_AVAILABLE
+    static CallStackUPtr ALWAYS_INLINE getCurrent(int32_t = 1) {
+        return CallStackUPtr(nullptr);
+    }
+#endif // !WEAKS_AVAILABLE
+
+#ifdef WEAKS_AVAILABLE
+    static void ALWAYS_INLINE logStack(const char* logtag, CallStack* stack = getCurrent().get(),
+                                       android_LogPriority priority = ANDROID_LOG_DEBUG) {
+        if (reinterpret_cast<uintptr_t>(logStackInternal) != 0 && stack != nullptr) {
+            logStackInternal(logtag, stack, priority);
+        } else {
+            ALOGW("CallStack::logStackInternal not linked");
+        }
+    }
+
+#else
+    static void ALWAYS_INLINE logStack(const char*, CallStack* = getCurrent().get(),
+                                       android_LogPriority = ANDROID_LOG_DEBUG) {
+    }
+#endif // !WEAKS_AVAILABLE
+
+#ifdef WEAKS_AVAILABLE
+    static String8 ALWAYS_INLINE stackToString(const char* prefix = nullptr,
+                                               const CallStack* stack = getCurrent().get()) {
+        if (reinterpret_cast<uintptr_t>(stackToStringInternal) != 0 && stack != nullptr) {
+            return stackToStringInternal(prefix, stack);
+        } else {
+            return String8("<CallStack package not linked>");
+        }
+    }
+#else // !WEAKS_AVAILABLE
+    static String8 ALWAYS_INLINE stackToString(const char* = nullptr,
+                                               const CallStack* = getCurrent().get()) {
+        return String8("<CallStack package not linked>");
+    }
+#endif // !WEAKS_AVAILABLE
+
+  private:
+#ifdef WEAKS_AVAILABLE
+    static CallStackUPtr CALLSTACK_WEAK getCurrentInternal(int32_t ignoreDepth);
+    static void CALLSTACK_WEAK logStackInternal(const char* logtag, const CallStack* stack,
+                                                android_LogPriority priority);
+    static String8 CALLSTACK_WEAK stackToStringInternal(const char* prefix, const CallStack* stack);
+    // The deleter is only invoked on non-null pointers. Hence it will never be
+    // invoked if CallStack is not linked.
+    static void CALLSTACK_WEAK deleteStack(CallStack* stack);
+#endif // WEAKS_AVAILABLE
+
     Vector<String8> mFrameLines;
 };