Loading libs/binder/BpBinder.cpp +23 −0 Original line number Diff line number Diff line Loading @@ -54,6 +54,11 @@ uint32_t BpBinder::sBinderProxyCountHighWatermark = 2500; // Another arbitrary value a binder count needs to drop below before another callback will be called uint32_t BpBinder::sBinderProxyCountLowWatermark = 2000; std::atomic<uint32_t> BpBinder::sBinderProxyCount(0); std::atomic<uint32_t> BpBinder::sBinderProxyCountWarned(0); static constexpr uint32_t kBinderProxyCountWarnInterval = 5000; // Log any transactions for which the data exceeds this size #define LOG_TRANSACTIONS_OVER_SIZE (300 * 1024) Loading Loading @@ -193,6 +198,18 @@ sp<BpBinder> BpBinder::create(int32_t handle) { } sTrackingMap[trackedUid]++; } uint32_t numProxies = sBinderProxyCount.fetch_add(1, std::memory_order_relaxed); uint32_t numLastWarned = sBinderProxyCountWarned.load(std::memory_order_relaxed); uint32_t numNextWarn = numLastWarned + kBinderProxyCountWarnInterval; if (numProxies >= numNextWarn) { // Multiple threads can get here, make sure only one of them gets to // update the warn counter. if (sBinderProxyCountWarned.compare_exchange_strong(numLastWarned, numNextWarn, std::memory_order_relaxed)) { ALOGW("Unexpectedly many live BinderProxies: %d\n", numProxies); } } return sp<BpBinder>::make(BinderHandle{handle}, trackedUid); } Loading Loading @@ -604,6 +621,7 @@ BpBinder::~BpBinder() { } } } --sBinderProxyCount; if (ipc) { ipc->expungeHandle(binderHandle(), this); Loading Loading @@ -688,6 +706,11 @@ uint32_t BpBinder::getBinderProxyCount(uint32_t uid) return 0; } uint32_t BpBinder::getBinderProxyCount() { return sBinderProxyCount.load(); } void BpBinder::getCountByUid(Vector<uint32_t>& uids, Vector<uint32_t>& counts) { AutoMutex _l(sTrackingLock); Loading libs/binder/include/binder/BpBinder.h +3 −0 Original line number Diff line number Diff line Loading @@ -88,6 +88,7 @@ public: static void setCountByUidEnabled(bool enable); static void setLimitCallback(binder_proxy_limit_callback cb); static void setBinderProxyCountWatermarks(int high, int low); static uint32_t getBinderProxyCount(); std::optional<int32_t> getDebugBinderHandle() const; Loading Loading @@ -209,6 +210,8 @@ private: static uint32_t sBinderProxyCountLowWatermark; static bool sBinderProxyThrottleCreate; static std::unordered_map<int32_t,uint32_t> sLastLimitCallbackMap; static std::atomic<uint32_t> sBinderProxyCount; static std::atomic<uint32_t> sBinderProxyCountWarned; }; } // namespace android Loading libs/binder/tests/binderLibTest.cpp +30 −0 Original line number Diff line number Diff line Loading @@ -1441,6 +1441,36 @@ TEST_F(BinderLibTest, HangingServices) { EXPECT_GE(epochMsAfter, epochMsBefore + delay); } TEST_F(BinderLibTest, BinderProxyCount) { Parcel data, reply; sp<IBinder> server = addServer(); ASSERT_NE(server, nullptr); uint32_t initialCount = BpBinder::getBinderProxyCount(); size_t iterations = 100; { uint32_t count = initialCount; std::vector<sp<IBinder> > proxies; sp<IBinder> proxy; // Create binder proxies and verify the count. for (size_t i = 0; i < iterations; i++) { ASSERT_THAT(server->transact(BINDER_LIB_TEST_CREATE_BINDER_TRANSACTION, data, &reply), StatusEq(NO_ERROR)); proxies.push_back(reply.readStrongBinder()); EXPECT_EQ(BpBinder::getBinderProxyCount(), ++count); } // Remove every other one and verify the count. auto it = proxies.begin(); for (size_t i = 0; it != proxies.end(); i++) { if (i % 2 == 0) { it = proxies.erase(it); EXPECT_EQ(BpBinder::getBinderProxyCount(), --count); } } } EXPECT_EQ(BpBinder::getBinderProxyCount(), initialCount); } class BinderLibRpcTestBase : public BinderLibTest { public: void SetUp() override { Loading Loading
libs/binder/BpBinder.cpp +23 −0 Original line number Diff line number Diff line Loading @@ -54,6 +54,11 @@ uint32_t BpBinder::sBinderProxyCountHighWatermark = 2500; // Another arbitrary value a binder count needs to drop below before another callback will be called uint32_t BpBinder::sBinderProxyCountLowWatermark = 2000; std::atomic<uint32_t> BpBinder::sBinderProxyCount(0); std::atomic<uint32_t> BpBinder::sBinderProxyCountWarned(0); static constexpr uint32_t kBinderProxyCountWarnInterval = 5000; // Log any transactions for which the data exceeds this size #define LOG_TRANSACTIONS_OVER_SIZE (300 * 1024) Loading Loading @@ -193,6 +198,18 @@ sp<BpBinder> BpBinder::create(int32_t handle) { } sTrackingMap[trackedUid]++; } uint32_t numProxies = sBinderProxyCount.fetch_add(1, std::memory_order_relaxed); uint32_t numLastWarned = sBinderProxyCountWarned.load(std::memory_order_relaxed); uint32_t numNextWarn = numLastWarned + kBinderProxyCountWarnInterval; if (numProxies >= numNextWarn) { // Multiple threads can get here, make sure only one of them gets to // update the warn counter. if (sBinderProxyCountWarned.compare_exchange_strong(numLastWarned, numNextWarn, std::memory_order_relaxed)) { ALOGW("Unexpectedly many live BinderProxies: %d\n", numProxies); } } return sp<BpBinder>::make(BinderHandle{handle}, trackedUid); } Loading Loading @@ -604,6 +621,7 @@ BpBinder::~BpBinder() { } } } --sBinderProxyCount; if (ipc) { ipc->expungeHandle(binderHandle(), this); Loading Loading @@ -688,6 +706,11 @@ uint32_t BpBinder::getBinderProxyCount(uint32_t uid) return 0; } uint32_t BpBinder::getBinderProxyCount() { return sBinderProxyCount.load(); } void BpBinder::getCountByUid(Vector<uint32_t>& uids, Vector<uint32_t>& counts) { AutoMutex _l(sTrackingLock); Loading
libs/binder/include/binder/BpBinder.h +3 −0 Original line number Diff line number Diff line Loading @@ -88,6 +88,7 @@ public: static void setCountByUidEnabled(bool enable); static void setLimitCallback(binder_proxy_limit_callback cb); static void setBinderProxyCountWatermarks(int high, int low); static uint32_t getBinderProxyCount(); std::optional<int32_t> getDebugBinderHandle() const; Loading Loading @@ -209,6 +210,8 @@ private: static uint32_t sBinderProxyCountLowWatermark; static bool sBinderProxyThrottleCreate; static std::unordered_map<int32_t,uint32_t> sLastLimitCallbackMap; static std::atomic<uint32_t> sBinderProxyCount; static std::atomic<uint32_t> sBinderProxyCountWarned; }; } // namespace android Loading
libs/binder/tests/binderLibTest.cpp +30 −0 Original line number Diff line number Diff line Loading @@ -1441,6 +1441,36 @@ TEST_F(BinderLibTest, HangingServices) { EXPECT_GE(epochMsAfter, epochMsBefore + delay); } TEST_F(BinderLibTest, BinderProxyCount) { Parcel data, reply; sp<IBinder> server = addServer(); ASSERT_NE(server, nullptr); uint32_t initialCount = BpBinder::getBinderProxyCount(); size_t iterations = 100; { uint32_t count = initialCount; std::vector<sp<IBinder> > proxies; sp<IBinder> proxy; // Create binder proxies and verify the count. for (size_t i = 0; i < iterations; i++) { ASSERT_THAT(server->transact(BINDER_LIB_TEST_CREATE_BINDER_TRANSACTION, data, &reply), StatusEq(NO_ERROR)); proxies.push_back(reply.readStrongBinder()); EXPECT_EQ(BpBinder::getBinderProxyCount(), ++count); } // Remove every other one and verify the count. auto it = proxies.begin(); for (size_t i = 0; it != proxies.end(); i++) { if (i % 2 == 0) { it = proxies.erase(it); EXPECT_EQ(BpBinder::getBinderProxyCount(), --count); } } } EXPECT_EQ(BpBinder::getBinderProxyCount(), initialCount); } class BinderLibRpcTestBase : public BinderLibTest { public: void SetUp() override { Loading