2222#include < binder/RpcServer.h>
2323#include < binder/RpcSession.h>
2424#include < cutils/trace.h>
25+ #include < gtest/gtest-spi.h>
2526#include < gtest/gtest.h>
2627#include < utils/CallStack.h>
2728
2829#include < malloc.h>
30+ #include < atomic>
2931#include < functional>
32+ #include < numeric>
3033#include < vector>
3134
3235using namespace android ::binder::impl;
3336
3437static android::String8 gEmpty (" " ); // make sure first allocation from optimization runs
3538
39+ struct State {
40+ State (std::vector<size_t >&& expectedMallocs) : expectedMallocs(std::move(expectedMallocs)) {}
41+ ~State () {
42+ size_t num = numMallocs.load ();
43+ if (expectedMallocs.size () != num) {
44+ ADD_FAILURE () << " Expected " << expectedMallocs.size () << " allocations, but got "
45+ << num;
46+ }
47+ }
48+ const std::vector<size_t > expectedMallocs;
49+ std::atomic<size_t > numMallocs;
50+ };
51+
3652struct DestructionAction {
3753 DestructionAction (std::function<void ()> f) : mF (std::move(f)) {}
3854 ~DestructionAction () { mF (); };
@@ -95,8 +111,7 @@ namespace LambdaHooks {
95111
96112// Action to execute when malloc is hit. Supports nesting. Malloc is not
97113// restricted when the allocation hook is being processed.
98- __attribute__ ((warn_unused_result))
99- DestructionAction OnMalloc(LambdaHooks::AllocationHook f) {
114+ __attribute__ ((warn_unused_result)) DestructionAction OnMalloc(LambdaHooks::AllocationHook f) {
100115 MallocHooks before = MallocHooks::save ();
101116 LambdaHooks::lambdas.emplace_back (std::move (f));
102117 LambdaHooks::lambda_malloc_hooks.overwrite ();
@@ -106,6 +121,22 @@ DestructionAction OnMalloc(LambdaHooks::AllocationHook f) {
106121 });
107122}
108123
124+ DestructionAction setExpectedMallocs (std::vector<size_t >&& expected) {
125+ auto state = std::make_shared<State>(std::move (expected));
126+ return OnMalloc ([state = state](size_t bytes) {
127+ size_t num = state->numMallocs .fetch_add (1 );
128+ if (num >= state->expectedMallocs .size () || state->expectedMallocs [num] != bytes) {
129+ ADD_FAILURE () << " Unexpected allocation number " << num << " of size " << bytes
130+ << " bytes" << std::endl
131+ << android::CallStack::stackToString (" UNEXPECTED ALLOCATION" ,
132+ android::CallStack::getCurrent (
133+ 4 /* ignoreDepth*/ )
134+ .get ())
135+ << std::endl;
136+ }
137+ });
138+ }
139+
109140// exported symbol, to force compiler not to optimize away pointers we set here
110141const void * imaginary_use;
111142
@@ -119,16 +150,53 @@ TEST(TestTheTest, OnMalloc) {
119150
120151 imaginary_use = new int [10 ];
121152 }
153+ delete[] reinterpret_cast <const int *>(imaginary_use);
122154 EXPECT_EQ (mallocs, 1u );
123155}
124156
157+ TEST (TestTheTest, OnMallocWithExpectedMallocs) {
158+ std::vector<size_t > expectedMallocs = {
159+ 4 ,
160+ 16 ,
161+ 8 ,
162+ };
163+ {
164+ const auto on_malloc = setExpectedMallocs (std::move (expectedMallocs));
165+ imaginary_use = new int32_t [1 ];
166+ delete[] reinterpret_cast <const int *>(imaginary_use);
167+ imaginary_use = new int32_t [4 ];
168+ delete[] reinterpret_cast <const int *>(imaginary_use);
169+ imaginary_use = new int32_t [2 ];
170+ delete[] reinterpret_cast <const int *>(imaginary_use);
171+ }
172+ }
173+
174+ TEST (TestTheTest, OnMallocWithExpectedMallocsWrongSize) {
175+ std::vector<size_t > expectedMallocs = {
176+ 4 ,
177+ 16 ,
178+ 100000 ,
179+ };
180+ EXPECT_NONFATAL_FAILURE (
181+ {
182+ const auto on_malloc = setExpectedMallocs (std::move (expectedMallocs));
183+ imaginary_use = new int32_t [1 ];
184+ delete[] reinterpret_cast <const int *>(imaginary_use);
185+ imaginary_use = new int32_t [4 ];
186+ delete[] reinterpret_cast <const int *>(imaginary_use);
187+ imaginary_use = new int32_t [2 ];
188+ delete[] reinterpret_cast <const int *>(imaginary_use);
189+ },
190+ " Unexpected allocation number 2 of size 8 bytes" );
191+ }
125192
126193__attribute__ ((warn_unused_result))
127194DestructionAction ScopeDisallowMalloc() {
128195 return OnMalloc ([&](size_t bytes) {
129- ADD_FAILURE () << " Unexpected allocation: " << bytes;
196+ FAIL () << " Unexpected allocation: " << bytes;
130197 using android::CallStack;
131- std::cout << CallStack::stackToString (" UNEXPECTED ALLOCATION" , CallStack::getCurrent (4 /* ignoreDepth*/ ).get ())
198+ std::cout << CallStack::stackToString (" UNEXPECTED ALLOCATION" ,
199+ CallStack::getCurrent (4 /* ignoreDepth*/ ).get ())
132200 << std::endl;
133201 });
134202}
@@ -224,6 +292,51 @@ TEST(BinderAllocation, SmallTransaction) {
224292 EXPECT_EQ (mallocs, 1u );
225293}
226294
295+ TEST (BinderAccessorAllocation, AddAccessorCheckService) {
296+ // Need to call defaultServiceManager() before checking malloc because it
297+ // will allocate an instance in the call_once
298+ const auto sm = defaultServiceManager ();
299+ const std::string kInstanceName1 = " foo.bar.IFoo/default" ;
300+ const std::string kInstanceName2 = " foo.bar.IFoo2/default" ;
301+ const String16 kInstanceName16 (kInstanceName1 .c_str ());
302+ std::vector<size_t > expectedMallocs = {
303+ // addAccessorProvider
304+ 112 , // new AccessorProvider
305+ 16 , // new AccessorProviderEntry
306+ // checkService
307+ 45 , // String8 from String16 in CppShim::checkService
308+ 128 , // writeInterfaceToken
309+ 16 , // getInjectedAccessor, new AccessorProviderEntry
310+ 66 , // getInjectedAccessor, String16
311+ 45 , // String8 from String16 in AccessorProvider::provide
312+ };
313+ std::set<std::string> supportedInstances = {kInstanceName1 , kInstanceName2 };
314+ auto onMalloc = setExpectedMallocs (std::move (expectedMallocs));
315+
316+ auto receipt =
317+ android::addAccessorProvider (std::move (supportedInstances),
318+ [&](const String16&) -> sp<IBinder> { return nullptr ; });
319+ EXPECT_FALSE (receipt.expired ());
320+
321+ sp<IBinder> binder = sm->checkService (kInstanceName16 );
322+
323+ status_t status = android::removeAccessorProvider (receipt);
324+ }
325+
326+ TEST (BinderAccessorAllocation, AddAccessorEmpty) {
327+ std::vector<size_t > expectedMallocs = {
328+ 48 , // From ALOGE with empty set of instances
329+ };
330+ std::set<std::string> supportedInstances = {};
331+ auto onMalloc = setExpectedMallocs (std::move (expectedMallocs));
332+
333+ auto receipt =
334+ android::addAccessorProvider (std::move (supportedInstances),
335+ [&](const String16&) -> sp<IBinder> { return nullptr ; });
336+
337+ EXPECT_TRUE (receipt.expired ());
338+ }
339+
227340TEST (RpcBinderAllocation, SetupRpcServer) {
228341 std::string tmp = getenv (" TMPDIR" ) ?: " /tmp" ;
229342 std::string addr = tmp + " /binderRpcBenchmark" ;
@@ -255,6 +368,7 @@ TEST(RpcBinderAllocation, SetupRpcServer) {
255368}
256369
257370int main (int argc, char ** argv) {
371+ LOG (INFO) << " Priming static log variables for binderAllocationLimits." ;
258372 if (getenv (" LIBC_HOOKS_ENABLE" ) == nullptr ) {
259373 CHECK (0 == setenv (" LIBC_HOOKS_ENABLE" , " 1" , true /* overwrite*/ ));
260374 execv (argv[0 ], argv);
0 commit comments