Merge "Merge "Merge "Merge "resolve merge conflicts of 21ef3ae3fd1dd2076c3b97efa09b3d58e799ce9f to android11-tests-dev" into android11-tests-dev am: bdf02cc54d" into android12-tests-dev am: fdca6ffb38" into android12L-tests-dev am: c1a6b27d21" am: c3c2643a8b am: 5639819569 am: bab2b5417f
Original change: https://android-review.googlesource.com/c/platform/system/core/+/1726290
Change-Id: If709246da0db705ed8e89f3939efe55af4270a71
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/init/epoll.cpp b/init/epoll.cpp
index 74d8aac..0580f86 100644
--- a/init/epoll.cpp
+++ b/init/epoll.cpp
@@ -23,6 +23,8 @@
#include <functional>
#include <map>
+#include <android-base/logging.h>
+
namespace android {
namespace init {
@@ -42,8 +44,11 @@
if (!events) {
return Error() << "Must specify events";
}
- auto sp = std::make_shared<decltype(handler)>(std::move(handler));
- auto [it, inserted] = epoll_handlers_.emplace(fd, std::move(sp));
+
+ Info info;
+ info.events = events;
+ info.handler = std::make_shared<decltype(handler)>(std::move(handler));
+ auto [it, inserted] = epoll_handlers_.emplace(fd, std::move(info));
if (!inserted) {
return Error() << "Cannot specify two epoll handlers for a given FD";
}
@@ -84,8 +89,14 @@
}
std::vector<std::shared_ptr<Handler>> pending_functions;
for (int i = 0; i < num_events; ++i) {
- auto sp = *reinterpret_cast<std::shared_ptr<Handler>*>(ev[i].data.ptr);
- pending_functions.emplace_back(std::move(sp));
+ auto& info = *reinterpret_cast<Info*>(ev[i].data.ptr);
+ if ((info.events & (EPOLLIN | EPOLLPRI)) == (EPOLLIN | EPOLLPRI) &&
+ (ev[i].events & EPOLLIN) != ev[i].events) {
+ // This handler wants to know about exception events, and just got one.
+ // Log something informational.
+ LOG(ERROR) << "Received unexpected epoll event set: " << ev[i].events;
+ }
+ pending_functions.emplace_back(info.handler);
}
return pending_functions;
diff --git a/init/epoll.h b/init/epoll.h
index 0df5289..f58ae8d 100644
--- a/init/epoll.h
+++ b/init/epoll.h
@@ -46,8 +46,13 @@
std::optional<std::chrono::milliseconds> timeout);
private:
+ struct Info {
+ std::shared_ptr<Handler> handler;
+ uint32_t events;
+ };
+
android::base::unique_fd epoll_fd_;
- std::map<int, std::shared_ptr<Handler>> epoll_handlers_;
+ std::map<int, Info> epoll_handlers_;
};
} // namespace init
diff --git a/init/init.cpp b/init/init.cpp
index 038f172..29f643e 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -33,7 +33,10 @@
#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
#include <sys/_system_properties.h>
+#include <filesystem>
+#include <fstream>
#include <functional>
+#include <iostream>
#include <map>
#include <memory>
#include <mutex>
@@ -580,10 +583,10 @@
static constexpr std::chrono::milliseconds kDiagnosticTimeout = 10s;
-static void HandleSignalFd() {
+static void HandleSignalFd(bool one_off) {
signalfd_siginfo siginfo;
auto started = std::chrono::steady_clock::now();
- for (;;) {
+ do {
ssize_t bytes_read = TEMP_FAILURE_RETRY(read(signal_fd, &siginfo, sizeof(siginfo)));
if (bytes_read < 0 && errno == EAGAIN) {
auto now = std::chrono::steady_clock::now();
@@ -601,7 +604,7 @@
return;
}
break;
- }
+ } while (!one_off);
switch (siginfo.ssi_signo) {
case SIGCHLD:
@@ -661,7 +664,9 @@
PLOG(FATAL) << "failed to create signalfd";
}
- if (auto result = epoll->RegisterHandler(signal_fd, HandleSignalFd); !result.ok()) {
+ constexpr int flags = EPOLLIN | EPOLLPRI;
+ auto handler = std::bind(HandleSignalFd, false);
+ if (auto result = epoll->RegisterHandler(signal_fd, handler, flags); !result.ok()) {
LOG(FATAL) << result.error();
}
}
@@ -790,6 +795,32 @@
return {};
}
+static void DumpPidFds(const std::string& prefix, pid_t pid) {
+ std::error_code ec;
+ std::string proc_dir = "/proc/" + std::to_string(pid) + "/fd";
+ for (const auto& entry : std::filesystem::directory_iterator(proc_dir)) {
+ std::string target;
+ if (android::base::Readlink(entry.path(), &target)) {
+ LOG(ERROR) << prefix << target;
+ } else {
+ LOG(ERROR) << prefix << entry.path();
+ }
+ }
+}
+
+static void DumpFile(const std::string& prefix, const std::string& file) {
+ std::ifstream fp(file);
+ if (!fp) {
+ LOG(ERROR) << "Could not open " << file;
+ return;
+ }
+
+ std::string line;
+ while (std::getline(fp, line)) {
+ LOG(ERROR) << prefix << line;
+ }
+}
+
int SecondStageMain(int argc, char** argv) {
if (REBOOT_BOOTLOADER_ON_PANIC) {
InstallRebootSignalHandlers();
@@ -999,11 +1030,23 @@
(*function)();
}
} else if (Service::is_exec_service_running()) {
+ static bool dumped_diagnostics = false;
std::chrono::duration<double> waited =
std::chrono::steady_clock::now() - Service::exec_service_started();
if (waited >= kDiagnosticTimeout) {
LOG(ERROR) << "Exec service is hung? Waited " << waited.count()
<< " without SIGCHLD";
+ if (!dumped_diagnostics) {
+ DumpPidFds("exec service opened: ", Service::exec_service_pid());
+
+ std::string status_file =
+ "/proc/" + std::to_string(Service::exec_service_pid()) + "/status";
+ DumpFile("exec service: ", status_file);
+ dumped_diagnostics = true;
+
+ LOG(INFO) << "Attempting to handle any stuck SIGCHLDs...";
+ HandleSignalFd(true);
+ }
}
}
if (!IsShuttingDown()) {
diff --git a/init/service.cpp b/init/service.cpp
index 077477a..0f24437 100644
--- a/init/service.cpp
+++ b/init/service.cpp
@@ -127,6 +127,7 @@
unsigned long Service::next_start_order_ = 1;
bool Service::is_exec_service_running_ = false;
+pid_t Service::exec_service_pid_ = -1;
std::chrono::time_point<std::chrono::steady_clock> Service::exec_service_started_;
Service::Service(const std::string& name, Subcontext* subcontext_for_restart_commands,
@@ -389,6 +390,7 @@
flags_ |= SVC_EXEC;
is_exec_service_running_ = true;
+ exec_service_pid_ = pid_;
exec_service_started_ = std::chrono::steady_clock::now();
LOG(INFO) << "SVC_EXEC service '" << name_ << "' pid " << pid_ << " (uid " << proc_attr_.uid
diff --git a/init/service.h b/init/service.h
index d233cbf..c314aa1 100644
--- a/init/service.h
+++ b/init/service.h
@@ -102,6 +102,7 @@
size_t CheckAllCommands() const { return onrestart_.CheckAllCommands(); }
static bool is_exec_service_running() { return is_exec_service_running_; }
+ static pid_t exec_service_pid() { return exec_service_pid_; }
static std::chrono::time_point<std::chrono::steady_clock> exec_service_started() {
return exec_service_started_;
}
diff --git a/init/sigchld_handler.cpp b/init/sigchld_handler.cpp
index 9b2c7d9..6fc64df 100644
--- a/init/sigchld_handler.cpp
+++ b/init/sigchld_handler.cpp
@@ -95,7 +95,10 @@
LOG(INFO) << name << " received signal " << siginfo.si_status << wait_string;
}
- if (!service) return pid;
+ if (!service) {
+ LOG(INFO) << name << " did not have an associated service entry and will not be reaped";
+ return pid;
+ }
service->Reap(siginfo);
diff --git a/libutils/Android.bp b/libutils/Android.bp
index 1b29285..7d6a6c5 100644
--- a/libutils/Android.bp
+++ b/libutils/Android.bp
@@ -76,6 +76,7 @@
"-Wall",
"-Werror",
"-Wno-exit-time-destructors",
+ "-DANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION",
],
header_libs: [
"libbase_headers",
diff --git a/libutils/Looper.cpp b/libutils/Looper.cpp
index 292425a..1a3f34b 100644
--- a/libutils/Looper.cpp
+++ b/libutils/Looper.cpp
@@ -117,14 +117,15 @@
int result = pthread_once(& gTLSOnce, initTLSKey);
LOG_ALWAYS_FATAL_IF(result != 0, "pthread_once failed");
- return (Looper*)pthread_getspecific(gTLSKey);
+ Looper* looper = (Looper*)pthread_getspecific(gTLSKey);
+ return sp<Looper>::fromExisting(looper);
}
sp<Looper> Looper::prepare(int opts) {
bool allowNonCallbacks = opts & PREPARE_ALLOW_NON_CALLBACKS;
sp<Looper> looper = Looper::getForThread();
if (looper == nullptr) {
- looper = new Looper(allowNonCallbacks);
+ looper = sp<Looper>::make(allowNonCallbacks);
Looper::setForThread(looper);
}
if (looper->getAllowNonCallbacks() != allowNonCallbacks) {
@@ -425,7 +426,11 @@
}
int Looper::addFd(int fd, int ident, int events, Looper_callbackFunc callback, void* data) {
- return addFd(fd, ident, events, callback ? new SimpleLooperCallback(callback) : nullptr, data);
+ sp<SimpleLooperCallback> looperCallback;
+ if (callback) {
+ looperCallback = sp<SimpleLooperCallback>::make(callback);
+ }
+ return addFd(fd, ident, events, looperCallback, data);
}
int Looper::addFd(int fd, int ident, int events, const sp<LooperCallback>& callback, void* data) {
diff --git a/libutils/NativeHandle.cpp b/libutils/NativeHandle.cpp
index d437a9f..819a603 100644
--- a/libutils/NativeHandle.cpp
+++ b/libutils/NativeHandle.cpp
@@ -20,7 +20,7 @@
namespace android {
sp<NativeHandle> NativeHandle::create(native_handle_t* handle, bool ownsHandle) {
- return handle ? new NativeHandle(handle, ownsHandle) : nullptr;
+ return handle ? sp<NativeHandle>::make(handle, ownsHandle) : nullptr;
}
NativeHandle::NativeHandle(native_handle_t* handle, bool ownsHandle)
diff --git a/libutils/Threads.cpp b/libutils/Threads.cpp
index 4dacdc6..e756fec 100644
--- a/libutils/Threads.cpp
+++ b/libutils/Threads.cpp
@@ -673,7 +673,7 @@
mThread = thread_id_t(-1);
// hold a strong reference on ourself
- mHoldSelf = this;
+ mHoldSelf = sp<Thread>::fromExisting(this);
mRunning = true;
diff --git a/libutils/include/utils/NativeHandle.h b/libutils/include/utils/NativeHandle.h
index 73fe804..f26a1a4 100644
--- a/libutils/include/utils/NativeHandle.h
+++ b/libutils/include/utils/NativeHandle.h
@@ -39,6 +39,8 @@
private:
// for access to the destructor
friend class LightRefBase<NativeHandle>;
+ // for access to the constructor
+ friend class sp<NativeHandle>;
NativeHandle(native_handle_t* handle, bool ownsHandle);
~NativeHandle();