diff options
Diffstat (limited to 'libs/binder/tests/binderAllocationLimits.cpp')
-rw-r--r-- | libs/binder/tests/binderAllocationLimits.cpp | 186 |
1 files changed, 0 insertions, 186 deletions
diff --git a/libs/binder/tests/binderAllocationLimits.cpp b/libs/binder/tests/binderAllocationLimits.cpp deleted file mode 100644 index e1f5ed5381..0000000000 --- a/libs/binder/tests/binderAllocationLimits.cpp +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Copyright (C) 2020 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 <android-base/logging.h> -#include <binder/Parcel.h> -#include <binder/IServiceManager.h> -#include <gtest/gtest.h> -#include <utils/CallStack.h> - -#include <malloc.h> -#include <functional> -#include <vector> - -struct DestructionAction { - DestructionAction(std::function<void()> f) : mF(std::move(f)) {} - ~DestructionAction() { mF(); }; -private: - std::function<void()> mF; -}; - -// Group of hooks -struct MallocHooks { - decltype(__malloc_hook) malloc_hook; - decltype(__realloc_hook) realloc_hook; - - static MallocHooks save() { - return { - .malloc_hook = __malloc_hook, - .realloc_hook = __realloc_hook, - }; - } - - void overwrite() const { - __malloc_hook = malloc_hook; - __realloc_hook = realloc_hook; - } -}; - -static const MallocHooks orig_malloc_hooks = MallocHooks::save(); - -// When malloc is hit, executes lambda. -namespace LambdaHooks { - using AllocationHook = std::function<void(size_t)>; - static std::vector<AllocationHook> lambdas = {}; - - static void* lambda_realloc_hook(void* ptr, size_t bytes, const void* arg); - static void* lambda_malloc_hook(size_t bytes, const void* arg); - - static const MallocHooks lambda_malloc_hooks = { - .malloc_hook = lambda_malloc_hook, - .realloc_hook = lambda_realloc_hook, - }; - - static void* lambda_malloc_hook(size_t bytes, const void* arg) { - { - orig_malloc_hooks.overwrite(); - lambdas.at(lambdas.size() - 1)(bytes); - lambda_malloc_hooks.overwrite(); - } - return orig_malloc_hooks.malloc_hook(bytes, arg); - } - - static void* lambda_realloc_hook(void* ptr, size_t bytes, const void* arg) { - { - orig_malloc_hooks.overwrite(); - lambdas.at(lambdas.size() - 1)(bytes); - lambda_malloc_hooks.overwrite(); - } - return orig_malloc_hooks.realloc_hook(ptr, bytes, arg); - } - -} - -// Action to execute when malloc is hit. Supports nesting. Malloc is not -// restricted when the allocation hook is being processed. -__attribute__((warn_unused_result)) -DestructionAction OnMalloc(LambdaHooks::AllocationHook f) { - MallocHooks before = MallocHooks::save(); - LambdaHooks::lambdas.emplace_back(std::move(f)); - LambdaHooks::lambda_malloc_hooks.overwrite(); - return DestructionAction([before]() { - before.overwrite(); - LambdaHooks::lambdas.pop_back(); - }); -} - -// exported symbol, to force compiler not to optimize away pointers we set here -const void* imaginary_use; - -TEST(TestTheTest, OnMalloc) { - size_t mallocs = 0; - { - const auto on_malloc = OnMalloc([&](size_t bytes) { - mallocs++; - EXPECT_EQ(bytes, 40); - }); - - imaginary_use = new int[10]; - } - EXPECT_EQ(mallocs, 1); -} - - -__attribute__((warn_unused_result)) -DestructionAction ScopeDisallowMalloc() { - return OnMalloc([&](size_t bytes) { - ADD_FAILURE() << "Unexpected allocation: " << bytes; - using android::CallStack; - std::cout << CallStack::stackToString("UNEXPECTED ALLOCATION", CallStack::getCurrent(4 /*ignoreDepth*/).get()) - << std::endl; - }); -} - -using android::IBinder; -using android::Parcel; -using android::String16; -using android::defaultServiceManager; -using android::sp; -using android::IServiceManager; - -static sp<IBinder> GetRemoteBinder() { - // This gets binder representing the service manager - // the current IServiceManager API doesn't expose the binder, and - // I want to avoid adding usages of the AIDL generated interface it - // is using underneath, so to avoid people copying it. - sp<IBinder> binder = defaultServiceManager()->checkService(String16("manager")); - EXPECT_NE(nullptr, binder); - return binder; -} - -TEST(BinderAllocation, ParcelOnStack) { - const auto m = ScopeDisallowMalloc(); - Parcel p; - imaginary_use = p.data(); -} - -TEST(BinderAllocation, GetServiceManager) { - defaultServiceManager(); // first call may alloc - const auto m = ScopeDisallowMalloc(); - defaultServiceManager(); -} - -// note, ping does not include interface descriptor -TEST(BinderAllocation, PingTransaction) { - sp<IBinder> a_binder = GetRemoteBinder(); - const auto m = ScopeDisallowMalloc(); - a_binder->pingBinder(); -} - -TEST(BinderAllocation, SmallTransaction) { - String16 empty_descriptor = String16(""); - sp<IServiceManager> manager = defaultServiceManager(); - - size_t mallocs = 0; - const auto on_malloc = OnMalloc([&](size_t bytes) { - mallocs++; - // Parcel should allocate a small amount by default - EXPECT_EQ(bytes, 128); - }); - manager->checkService(empty_descriptor); - - EXPECT_EQ(mallocs, 1); -} - -int main(int argc, char** argv) { - if (getenv("LIBC_HOOKS_ENABLE") == nullptr) { - CHECK(0 == setenv("LIBC_HOOKS_ENABLE", "1", true /*overwrite*/)); - execv(argv[0], argv); - return 1; - } - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} |