diff options
author | 2020-12-02 23:34:15 +0000 | |
---|---|---|
committer | 2020-12-02 23:39:04 +0000 | |
commit | cde5d53acb0342dde317de78f981908a9d205bdc (patch) | |
tree | 41f2d2ab20a09ac101a54dbd7fdf6303f727bce7 | |
parent | 4aaa310584fcce57ec12eaf15a77312a9eb7c648 (diff) |
binderSafeInterfaceTest: avoid zombie
On 64-bit cuttlefish (and some other reported devices), this test was
failing to shut down properly (became a zombie process). In order to fix
this, this now forks a server much earlier, to avoid child processes
holding any resources.
Also, as an effect:
- no longer starting threadpool (only 1 thread is needed to process
test)
- using prctl to exit child process even in error cases
Bug: 174621701
Test: atest binderSafeInterfaceTest
(on 64-bit cuttlefish, no longer hangs)
Change-Id: I326c42d0664e18c478efce83f935841e6dbfa8f3
-rw-r--r-- | libs/binder/tests/binderSafeInterfaceTest.cpp | 58 |
1 files changed, 26 insertions, 32 deletions
diff --git a/libs/binder/tests/binderSafeInterfaceTest.cpp b/libs/binder/tests/binderSafeInterfaceTest.cpp index 2f9d85efcf..ffb3ef2c70 100644 --- a/libs/binder/tests/binderSafeInterfaceTest.cpp +++ b/libs/binder/tests/binderSafeInterfaceTest.cpp @@ -36,12 +36,15 @@ #include <optional> #include <sys/eventfd.h> +#include <sys/prctl.h> using namespace std::chrono_literals; // NOLINT - google-build-using-namespace namespace android { namespace tests { +static const String16 kServiceName("SafeInterfaceTest"); + enum class TestEnum : uint32_t { INVALID = 0, INITIAL = 1, @@ -601,40 +604,13 @@ private: static constexpr const char* getLogTag() { return "SafeInterfaceTest"; } sp<ISafeInterfaceTest> getRemoteService() { -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wexit-time-destructors" - static std::mutex sMutex; - static sp<ISafeInterfaceTest> sService; - static sp<IBinder> sDeathToken = new BBinder; -#pragma clang diagnostic pop + sp<IBinder> binder = defaultServiceManager()->getService(kServiceName); + sp<ISafeInterfaceTest> iface = interface_cast<ISafeInterfaceTest>(binder); + EXPECT_TRUE(iface != nullptr); - std::unique_lock<decltype(sMutex)> lock; - if (sService == nullptr) { - ALOG(LOG_INFO, getLogTag(), "Forking remote process"); - pid_t forkPid = fork(); - EXPECT_NE(forkPid, -1); - - const String16 serviceName("SafeInterfaceTest"); - - if (forkPid == 0) { - ALOG(LOG_INFO, getLogTag(), "Remote process checking in"); - sp<ISafeInterfaceTest> nativeService = new BnSafeInterfaceTest; - defaultServiceManager()->addService(serviceName, - IInterface::asBinder(nativeService)); - ProcessState::self()->startThreadPool(); - IPCThreadState::self()->joinThreadPool(); - // We shouldn't get to this point - [&]() { FAIL(); }(); - } + iface->setDeathToken(new BBinder); - sp<IBinder> binder = defaultServiceManager()->getService(serviceName); - sService = interface_cast<ISafeInterfaceTest>(binder); - EXPECT_TRUE(sService != nullptr); - - sService->setDeathToken(sDeathToken); - } - - return sService; + return iface; } }; @@ -840,5 +816,23 @@ TEST_F(SafeInterfaceTest, TestIncrementTwo) { ASSERT_EQ(b + 1, bPlusOne); } +extern "C" int main(int argc, char **argv) { + testing::InitGoogleTest(&argc, argv); + + if (fork() == 0) { + prctl(PR_SET_PDEATHSIG, SIGHUP); + sp<BnSafeInterfaceTest> nativeService = new BnSafeInterfaceTest; + status_t status = defaultServiceManager()->addService(kServiceName, nativeService); + if (status != OK) { + ALOG(LOG_INFO, "SafeInterfaceServer", "could not register"); + return EXIT_FAILURE; + } + IPCThreadState::self()->joinThreadPool(); + return EXIT_FAILURE; + } + + return RUN_ALL_TESTS(); +} + } // namespace tests } // namespace android |