Merge "[MTE] only upgrade to SYNC mode for MTE crashes"
diff --git a/debuggerd/proto/tombstone.proto b/debuggerd/proto/tombstone.proto
index a0f2f82..f0d3d3f 100644
--- a/debuggerd/proto/tombstone.proto
+++ b/debuggerd/proto/tombstone.proto
@@ -1,3 +1,12 @@
+//
+// Protobuf definition for Android tombstones.
+//
+// An app can get hold of these for any `REASON_CRASH_NATIVE` instance of
+// `android.app.ApplicationExitInfo`.
+//
+// https://developer.android.com/reference/android/app/ApplicationExitInfo#getTraceInputStream()
+//
+
 syntax = "proto3";
 
 option java_package = "com.android.server.os";
diff --git a/init/README.md b/init/README.md
index fed81db..7b3d32a 100644
--- a/init/README.md
+++ b/init/README.md
@@ -352,9 +352,10 @@
 
 `socket <name> <type> <perm> [ <user> [ <group> [ <seclabel> ] ] ]`
 > Create a UNIX domain socket named /dev/socket/_name_ and pass its fd to the
-  launched process.  _type_ must be "dgram", "stream" or "seqpacket".  _type_
-  may end with "+passcred" to enable SO_PASSCRED on the socket. User and
-  group default to 0.  'seclabel' is the SELinux security context for the
+  launched process.  The socket is created synchronously when the service starts.
+  _type_ must be "dgram", "stream" or "seqpacket".  _type_ may end with "+passcred"
+  to enable SO_PASSCRED on the socket or "+listen" to synchronously make it a listening socket.
+  User and group default to 0.  'seclabel' is the SELinux security context for the
   socket.  It defaults to the service security context, as specified by
   seclabel or computed based on the service executable file security context.
   For native executables see libcutils android\_get\_control\_socket().
diff --git a/init/property_service.cpp b/init/property_service.cpp
index 7e92538..c2ba8d5 100644
--- a/init/property_service.cpp
+++ b/init/property_service.cpp
@@ -1404,7 +1404,8 @@
     StartSendingMessages();
 
     if (auto result = CreateSocket(PROP_SERVICE_NAME, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
-                                   false, 0666, 0, 0, {});
+                                   /*passcred=*/false, /*should_listen=*/false, 0666, /*uid=*/0,
+                                   /*gid=*/0, /*socketcon=*/{});
         result.ok()) {
         property_set_fd = *result;
     } else {
diff --git a/init/service_parser.cpp b/init/service_parser.cpp
index 32c57c4..24a2024 100644
--- a/init/service_parser.cpp
+++ b/init/service_parser.cpp
@@ -434,11 +434,14 @@
                        << "' instead.";
     }
 
-    if (types.size() > 1) {
-        if (types.size() == 2 && types[1] == "passcred") {
+    for (size_t i = 1; i < types.size(); i++) {
+        if (types[i] == "passcred") {
             socket.passcred = true;
+        } else if (types[i] == "listen") {
+            socket.listen = true;
         } else {
-            return Error() << "Only 'passcred' may be used to modify the socket type";
+            return Error() << "Unknown socket type decoration '" << types[i]
+                           << "'. Known values are ['passcred', 'listen']";
         }
     }
 
diff --git a/init/service_utils.cpp b/init/service_utils.cpp
index eed5c65..d19f5ee 100644
--- a/init/service_utils.cpp
+++ b/init/service_utils.cpp
@@ -168,7 +168,8 @@
 
 Result<Descriptor> SocketDescriptor::Create(const std::string& global_context) const {
     const auto& socket_context = context.empty() ? global_context : context;
-    auto result = CreateSocket(name, type | SOCK_CLOEXEC, passcred, perm, uid, gid, socket_context);
+    auto result = CreateSocket(name, type | SOCK_CLOEXEC, passcred, listen, perm, uid, gid,
+                               socket_context);
     if (!result.ok()) {
         return result.error();
     }
diff --git a/init/service_utils.h b/init/service_utils.h
index 9b65dca..65a2012 100644
--- a/init/service_utils.h
+++ b/init/service_utils.h
@@ -54,6 +54,7 @@
     int perm = 0;
     std::string context;
     bool passcred = false;
+    bool listen = false;
     bool persist = false;
 
     // Create() creates the named unix domain socket in /dev/socket and returns a Descriptor object.
diff --git a/init/util.cpp b/init/util.cpp
index 2d40142..3d42855 100644
--- a/init/util.cpp
+++ b/init/util.cpp
@@ -89,8 +89,8 @@
  * daemon. We communicate the file descriptor's value via the environment
  * variable ANDROID_SOCKET_ENV_PREFIX<name> ("ANDROID_SOCKET_foo").
  */
-Result<int> CreateSocket(const std::string& name, int type, bool passcred, mode_t perm, uid_t uid,
-                         gid_t gid, const std::string& socketcon) {
+Result<int> CreateSocket(const std::string& name, int type, bool passcred, bool should_listen,
+                         mode_t perm, uid_t uid, gid_t gid, const std::string& socketcon) {
     if (!socketcon.empty()) {
         if (setsockcreatecon(socketcon.c_str()) == -1) {
             return ErrnoError() << "setsockcreatecon(\"" << socketcon << "\") failed";
@@ -145,6 +145,9 @@
     if (fchmodat(AT_FDCWD, addr.sun_path, perm, AT_SYMLINK_NOFOLLOW)) {
         return ErrnoError() << "Failed to fchmodat socket '" << addr.sun_path << "'";
     }
+    if (should_listen && listen(fd, /* use OS maximum */ 1 << 30)) {
+        return ErrnoError() << "Failed to listen on socket '" << addr.sun_path << "'";
+    }
 
     LOG(INFO) << "Created socket '" << addr.sun_path << "'"
               << ", mode " << std::oct << perm << std::dec
diff --git a/init/util.h b/init/util.h
index 0181bf0..e58e70e 100644
--- a/init/util.h
+++ b/init/util.h
@@ -44,8 +44,8 @@
 
 extern void (*trigger_shutdown)(const std::string& command);
 
-Result<int> CreateSocket(const std::string& name, int type, bool passcred, mode_t perm, uid_t uid,
-                         gid_t gid, const std::string& socketcon);
+Result<int> CreateSocket(const std::string& name, int type, bool passcred, bool should_listen,
+                         mode_t perm, uid_t uid, gid_t gid, const std::string& socketcon);
 
 Result<std::string> ReadFile(const std::string& path);
 Result<void> WriteFile(const std::string& path, const std::string& content);
diff --git a/libutils/Android.bp b/libutils/Android.bp
index 7939e82..c744b53 100644
--- a/libutils/Android.bp
+++ b/libutils/Android.bp
@@ -299,6 +299,7 @@
 
     srcs: [
         "BitSet_test.cpp",
+        "CallStack_test.cpp",
         "Errors_test.cpp",
         "FileMap_test.cpp",
         "LruCache_test.cpp",
@@ -319,11 +320,14 @@
                 "SystemClock_test.cpp",
             ],
             shared_libs: [
-                "libz",
-                "liblog",
-                "libcutils",
-                "libutils",
                 "libbase",
+                "libcutils",
+                "liblog",
+                "liblzma",
+                "libunwindstack",
+                "libutils",
+                "libutilscallstack",
+                "libz",
             ],
         },
         linux: {
@@ -334,9 +338,12 @@
         },
         host: {
             static_libs: [
-                "libutils",
-                "liblog",
                 "libbase",
+                "liblog",
+                "liblzma",
+                "libunwindstack_no_dex",
+                "libutils",
+                "libutilscallstack",
             ],
         },
     },
diff --git a/libutils/CallStack.cpp b/libutils/CallStack.cpp
index f19ba6a..4dcb35b 100644
--- a/libutils/CallStack.cpp
+++ b/libutils/CallStack.cpp
@@ -49,7 +49,7 @@
     unwindstack::AndroidUnwinderData data;
     std::optional<pid_t> tid_val;
     if (tid != -1) {
-        *tid_val = tid;
+        tid_val = tid;
     }
     if (!unwinder.Unwind(tid_val, data)) {
         ALOGW("%s: Failed to unwind callstack: %s", __FUNCTION__, data.GetErrorString().c_str());
diff --git a/libutils/CallStack_test.cpp b/libutils/CallStack_test.cpp
new file mode 100644
index 0000000..2ea1911
--- /dev/null
+++ b/libutils/CallStack_test.cpp
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2022 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 <unistd.h>
+
+#include <thread>
+
+#include <android-base/threads.h>
+#include <gtest/gtest.h>
+#include <utils/CallStack.h>
+
+[[clang::noinline]] extern "C" void CurrentCaller(android::String8& backtrace) {
+    android::CallStack cs;
+    cs.update();
+    backtrace = cs.toString();
+}
+
+TEST(CallStackTest, current_backtrace) {
+    android::String8 backtrace;
+    CurrentCaller(backtrace);
+
+    ASSERT_NE(-1, backtrace.find("(CurrentCaller")) << "Full backtrace:\n" << backtrace;
+}
+
+[[clang::noinline]] extern "C" void ThreadBusyWait(std::atomic<pid_t>* tid, volatile bool* done) {
+    *tid = android::base::GetThreadId();
+    while (!*done) {
+    }
+}
+
+TEST(CallStackTest, thread_backtrace) {
+    // Use a volatile to avoid any problems unwinding since sometimes
+    // accessing a std::atomic does not include unwind data at every
+    // instruction and leads to failed unwinds.
+    volatile bool done = false;
+    std::atomic<pid_t> tid = -1;
+    std::thread thread([&tid, &done]() { ThreadBusyWait(&tid, &done); });
+
+    while (tid == -1) {
+    }
+
+    android::CallStack cs;
+    cs.update(0, tid);
+
+    done = true;
+    thread.join();
+
+    ASSERT_NE(-1, cs.toString().find("(ThreadBusyWait")) << "Full backtrace:\n" << cs.toString();
+}