1dc87c52cd5645dd87380114462211574b63e6353John Reck/* 2dc87c52cd5645dd87380114462211574b63e6353John Reck * Copyright (C) 2016 The Android Open Source Project 3dc87c52cd5645dd87380114462211574b63e6353John Reck * 4dc87c52cd5645dd87380114462211574b63e6353John Reck * Licensed under the Apache License, Version 2.0 (the "License"); 5dc87c52cd5645dd87380114462211574b63e6353John Reck * you may not use this file except in compliance with the License. 6dc87c52cd5645dd87380114462211574b63e6353John Reck * You may obtain a copy of the License at 7dc87c52cd5645dd87380114462211574b63e6353John Reck * 8dc87c52cd5645dd87380114462211574b63e6353John Reck * http://www.apache.org/licenses/LICENSE-2.0 9dc87c52cd5645dd87380114462211574b63e6353John Reck * 10dc87c52cd5645dd87380114462211574b63e6353John Reck * Unless required by applicable law or agreed to in writing, software 11dc87c52cd5645dd87380114462211574b63e6353John Reck * distributed under the License is distributed on an "AS IS" BASIS, 12dc87c52cd5645dd87380114462211574b63e6353John Reck * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13dc87c52cd5645dd87380114462211574b63e6353John Reck * See the License for the specific language governing permissions and 14dc87c52cd5645dd87380114462211574b63e6353John Reck * limitations under the License. 15dc87c52cd5645dd87380114462211574b63e6353John Reck */ 16dc87c52cd5645dd87380114462211574b63e6353John Reck 17dc87c52cd5645dd87380114462211574b63e6353John Reck#include "gtest/gtest.h" 18dc87c52cd5645dd87380114462211574b63e6353John Reck 19dc87c52cd5645dd87380114462211574b63e6353John Reck#include "Caches.h" 20dc87c52cd5645dd87380114462211574b63e6353John Reck#include "thread/TaskManager.h" 21dc87c52cd5645dd87380114462211574b63e6353John Reck#include "tests/common/TestUtils.h" 22dc87c52cd5645dd87380114462211574b63e6353John Reck 23dc87c52cd5645dd87380114462211574b63e6353John Reck#include <memunreachable/memunreachable.h> 24dc87c52cd5645dd87380114462211574b63e6353John Reck 25dc87c52cd5645dd87380114462211574b63e6353John Reck#include <cstdio> 26dc87c52cd5645dd87380114462211574b63e6353John Reck#include <iostream> 27dc87c52cd5645dd87380114462211574b63e6353John Reck#include <map> 28dc87c52cd5645dd87380114462211574b63e6353John Reck#include <unordered_set> 29dc87c52cd5645dd87380114462211574b63e6353John Reck#include <signal.h> 30dc87c52cd5645dd87380114462211574b63e6353John Reck#include <unistd.h> 31dc87c52cd5645dd87380114462211574b63e6353John Reck 32dc87c52cd5645dd87380114462211574b63e6353John Reckusing namespace std; 33dc87c52cd5645dd87380114462211574b63e6353John Reckusing namespace android; 34dc87c52cd5645dd87380114462211574b63e6353John Reckusing namespace android::uirenderer; 35dc87c52cd5645dd87380114462211574b63e6353John Reck 36dc87c52cd5645dd87380114462211574b63e6353John Reckstatic auto CRASH_SIGNALS = { 37dc87c52cd5645dd87380114462211574b63e6353John Reck SIGABRT, 38dc87c52cd5645dd87380114462211574b63e6353John Reck SIGSEGV, 39dc87c52cd5645dd87380114462211574b63e6353John Reck SIGBUS, 40dc87c52cd5645dd87380114462211574b63e6353John Reck}; 41dc87c52cd5645dd87380114462211574b63e6353John Reck 42dc87c52cd5645dd87380114462211574b63e6353John Reckstatic map<int, struct sigaction> gSigChain; 43dc87c52cd5645dd87380114462211574b63e6353John Reck 44dc87c52cd5645dd87380114462211574b63e6353John Reckstatic void gtestSigHandler(int sig, siginfo_t* siginfo, void* context) { 45dc87c52cd5645dd87380114462211574b63e6353John Reck auto testinfo = ::testing::UnitTest::GetInstance()->current_test_info(); 46dc87c52cd5645dd87380114462211574b63e6353John Reck printf("[ FAILED ] %s.%s\n", testinfo->test_case_name(), 47dc87c52cd5645dd87380114462211574b63e6353John Reck testinfo->name()); 48dc87c52cd5645dd87380114462211574b63e6353John Reck printf("[ FATAL! ] Process crashed, aborting tests!\n"); 49dc87c52cd5645dd87380114462211574b63e6353John Reck fflush(stdout); 50dc87c52cd5645dd87380114462211574b63e6353John Reck 51dc87c52cd5645dd87380114462211574b63e6353John Reck // restore the default sighandler and re-raise 52dc87c52cd5645dd87380114462211574b63e6353John Reck struct sigaction sa = gSigChain[sig]; 53dc87c52cd5645dd87380114462211574b63e6353John Reck sigaction(sig, &sa, nullptr); 54dc87c52cd5645dd87380114462211574b63e6353John Reck raise(sig); 55dc87c52cd5645dd87380114462211574b63e6353John Reck} 56dc87c52cd5645dd87380114462211574b63e6353John Reck 57dc87c52cd5645dd87380114462211574b63e6353John Reckstatic void logUnreachable(initializer_list<UnreachableMemoryInfo> infolist) { 58dc87c52cd5645dd87380114462211574b63e6353John Reck // merge them all 59dc87c52cd5645dd87380114462211574b63e6353John Reck UnreachableMemoryInfo merged; 60dc87c52cd5645dd87380114462211574b63e6353John Reck unordered_set<uintptr_t> addrs; 61dc87c52cd5645dd87380114462211574b63e6353John Reck merged.allocation_bytes = 0; 62dc87c52cd5645dd87380114462211574b63e6353John Reck merged.leak_bytes = 0; 63dc87c52cd5645dd87380114462211574b63e6353John Reck merged.num_allocations = 0; 64dc87c52cd5645dd87380114462211574b63e6353John Reck merged.num_leaks = 0; 65dc87c52cd5645dd87380114462211574b63e6353John Reck for (auto& info : infolist) { 66dc87c52cd5645dd87380114462211574b63e6353John Reck // We'll be a little hazzy about these ones and just hope the biggest 67dc87c52cd5645dd87380114462211574b63e6353John Reck // is the most accurate 68dc87c52cd5645dd87380114462211574b63e6353John Reck merged.allocation_bytes = max(merged.allocation_bytes, info.allocation_bytes); 69dc87c52cd5645dd87380114462211574b63e6353John Reck merged.num_allocations = max(merged.num_allocations, info.num_allocations); 70dc87c52cd5645dd87380114462211574b63e6353John Reck for (auto& leak : info.leaks) { 71dc87c52cd5645dd87380114462211574b63e6353John Reck if (addrs.find(leak.begin) == addrs.end()) { 72dc87c52cd5645dd87380114462211574b63e6353John Reck merged.leaks.push_back(leak); 73dc87c52cd5645dd87380114462211574b63e6353John Reck merged.num_leaks++; 74dc87c52cd5645dd87380114462211574b63e6353John Reck merged.leak_bytes += leak.size; 75dc87c52cd5645dd87380114462211574b63e6353John Reck addrs.insert(leak.begin); 76dc87c52cd5645dd87380114462211574b63e6353John Reck } 77dc87c52cd5645dd87380114462211574b63e6353John Reck } 78dc87c52cd5645dd87380114462211574b63e6353John Reck } 79dc87c52cd5645dd87380114462211574b63e6353John Reck 80dc87c52cd5645dd87380114462211574b63e6353John Reck // Now log the result 81dc87c52cd5645dd87380114462211574b63e6353John Reck if (merged.num_leaks) { 82dc87c52cd5645dd87380114462211574b63e6353John Reck cout << endl << "Leaked memory!" << endl; 8388737a05b39c67deaccf30d64348ae1277dcf90fJohn Reck if (!merged.leaks[0].backtrace.num_frames) { 84dc87c52cd5645dd87380114462211574b63e6353John Reck cout << "Re-run with 'setprop libc.debug.malloc.program hwui_unit_test'" 85dc87c52cd5645dd87380114462211574b63e6353John Reck << endl << "and 'setprop libc.debug.malloc.options backtrace=8'" 86dc87c52cd5645dd87380114462211574b63e6353John Reck << " to get backtraces" << endl; 87dc87c52cd5645dd87380114462211574b63e6353John Reck } 88dc87c52cd5645dd87380114462211574b63e6353John Reck cout << merged.ToString(false); 89dc87c52cd5645dd87380114462211574b63e6353John Reck } 90dc87c52cd5645dd87380114462211574b63e6353John Reck} 91dc87c52cd5645dd87380114462211574b63e6353John Reck 92dc87c52cd5645dd87380114462211574b63e6353John Reckstatic void checkForLeaks() { 93dc87c52cd5645dd87380114462211574b63e6353John Reck // TODO: Until we can shutdown the RT thread we need to do this in 94dc87c52cd5645dd87380114462211574b63e6353John Reck // two passes as GetUnreachableMemory has limited insight into 95dc87c52cd5645dd87380114462211574b63e6353John Reck // thread-local caches so some leaks will not be properly tagged as leaks 96dc87c52cd5645dd87380114462211574b63e6353John Reck nsecs_t before = systemTime(); 97dc87c52cd5645dd87380114462211574b63e6353John Reck UnreachableMemoryInfo rtMemInfo; 98dc87c52cd5645dd87380114462211574b63e6353John Reck TestUtils::runOnRenderThread([&rtMemInfo](renderthread::RenderThread& thread) { 99dc87c52cd5645dd87380114462211574b63e6353John Reck if (Caches::hasInstance()) { 100dc87c52cd5645dd87380114462211574b63e6353John Reck Caches::getInstance().tasks.stop(); 101dc87c52cd5645dd87380114462211574b63e6353John Reck } 102dc87c52cd5645dd87380114462211574b63e6353John Reck // Check for leaks 103dc87c52cd5645dd87380114462211574b63e6353John Reck if (!GetUnreachableMemory(rtMemInfo)) { 104dc87c52cd5645dd87380114462211574b63e6353John Reck cerr << "Failed to get unreachable memory!" << endl; 105dc87c52cd5645dd87380114462211574b63e6353John Reck return; 106dc87c52cd5645dd87380114462211574b63e6353John Reck } 107dc87c52cd5645dd87380114462211574b63e6353John Reck }); 108dc87c52cd5645dd87380114462211574b63e6353John Reck UnreachableMemoryInfo uiMemInfo; 109dc87c52cd5645dd87380114462211574b63e6353John Reck if (!GetUnreachableMemory(uiMemInfo)) { 110dc87c52cd5645dd87380114462211574b63e6353John Reck cerr << "Failed to get unreachable memory!" << endl; 111dc87c52cd5645dd87380114462211574b63e6353John Reck return; 112dc87c52cd5645dd87380114462211574b63e6353John Reck } 113dc87c52cd5645dd87380114462211574b63e6353John Reck logUnreachable({rtMemInfo, uiMemInfo}); 114dc87c52cd5645dd87380114462211574b63e6353John Reck nsecs_t after = systemTime(); 115dc87c52cd5645dd87380114462211574b63e6353John Reck cout << "Leak check took " << ns2ms(after - before) << "ms" << endl; 116dc87c52cd5645dd87380114462211574b63e6353John Reck} 117dc87c52cd5645dd87380114462211574b63e6353John Reck 118dc87c52cd5645dd87380114462211574b63e6353John Reckint main(int argc, char* argv[]) { 119dc87c52cd5645dd87380114462211574b63e6353John Reck // Register a crash handler 120dc87c52cd5645dd87380114462211574b63e6353John Reck struct sigaction sa; 121dc87c52cd5645dd87380114462211574b63e6353John Reck memset(&sa, 0, sizeof(sa)); 122dc87c52cd5645dd87380114462211574b63e6353John Reck sa.sa_sigaction = >estSigHandler; 123dc87c52cd5645dd87380114462211574b63e6353John Reck sa.sa_flags = SA_SIGINFO; 124dc87c52cd5645dd87380114462211574b63e6353John Reck for (auto sig : CRASH_SIGNALS) { 125dc87c52cd5645dd87380114462211574b63e6353John Reck struct sigaction old_sa; 126dc87c52cd5645dd87380114462211574b63e6353John Reck sigaction(sig, &sa, &old_sa); 127dc87c52cd5645dd87380114462211574b63e6353John Reck gSigChain.insert(pair<int, struct sigaction>(sig, old_sa)); 128dc87c52cd5645dd87380114462211574b63e6353John Reck } 129dc87c52cd5645dd87380114462211574b63e6353John Reck 130dc87c52cd5645dd87380114462211574b63e6353John Reck // Run the tests 131dc87c52cd5645dd87380114462211574b63e6353John Reck testing::InitGoogleTest(&argc, argv); 132dc87c52cd5645dd87380114462211574b63e6353John Reck int ret = RUN_ALL_TESTS(); 133dc87c52cd5645dd87380114462211574b63e6353John Reck checkForLeaks(); 134dc87c52cd5645dd87380114462211574b63e6353John Reck return ret; 135dc87c52cd5645dd87380114462211574b63e6353John Reck} 136dc87c52cd5645dd87380114462211574b63e6353John Reck 137