summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorandroid-build-team Robot2018-05-16 02:22:42 -0500
committerandroid-build-team Robot2018-05-16 02:22:42 -0500
commit7c365bcc92616b3b672d47205c10ef9b33c7f0fd (patch)
tree081033e8febc079a34544441a62dbd99b87da1c5
parent0ec0f4cb6ca15c7f54c22a885730fe33acfadd62 (diff)
parent05dca7ae962b2c9f7b038cea21cf318468a18404 (diff)
downloadplatform-system-core-7c365bcc92616b3b672d47205c10ef9b33c7f0fd.tar.gz
platform-system-core-7c365bcc92616b3b672d47205c10ef9b33c7f0fd.tar.xz
platform-system-core-7c365bcc92616b3b672d47205c10ef9b33c7f0fd.zip
Snap for 4784261 from 05dca7ae962b2c9f7b038cea21cf318468a18404 to pi-release
Change-Id: I274d523e2a7d8733586aa73a39583c1e01d5dbb6
-rw-r--r--libmemunreachable/MemUnreachable.cpp15
-rw-r--r--libmemunreachable/include/memunreachable/memunreachable.h7
-rw-r--r--libmemunreachable/tests/MemUnreachable_test.cpp66
3 files changed, 73 insertions, 15 deletions
diff --git a/libmemunreachable/MemUnreachable.cpp b/libmemunreachable/MemUnreachable.cpp
index 24fdc7f37..529a0437e 100644
--- a/libmemunreachable/MemUnreachable.cpp
+++ b/libmemunreachable/MemUnreachable.cpp
@@ -495,6 +495,21 @@ std::string UnreachableMemoryInfo::ToString(bool log_contents) const {
495 return oss.str(); 495 return oss.str();
496} 496}
497 497
498UnreachableMemoryInfo::~UnreachableMemoryInfo() {
499 // Clear the memory that holds the leaks, otherwise the next attempt to
500 // detect leaks may find the old data (for example in the jemalloc tcache)
501 // and consider all the leaks to be referenced.
502 memset(leaks.data(), 0, leaks.capacity() * sizeof(Leak));
503
504 std::vector<Leak> tmp;
505 leaks.swap(tmp);
506
507 // Disable and re-enable malloc to flush the jemalloc tcache to make sure
508 // there are no copies of the leaked pointer addresses there.
509 malloc_disable();
510 malloc_enable();
511}
512
498std::string GetUnreachableMemoryString(bool log_contents, size_t limit) { 513std::string GetUnreachableMemoryString(bool log_contents, size_t limit) {
499 UnreachableMemoryInfo info; 514 UnreachableMemoryInfo info;
500 if (!GetUnreachableMemory(info, limit)) { 515 if (!GetUnreachableMemory(info, limit)) {
diff --git a/libmemunreachable/include/memunreachable/memunreachable.h b/libmemunreachable/include/memunreachable/memunreachable.h
index 438fcafe1..c028eabf2 100644
--- a/libmemunreachable/include/memunreachable/memunreachable.h
+++ b/libmemunreachable/include/memunreachable/memunreachable.h
@@ -62,12 +62,7 @@ struct UnreachableMemoryInfo {
62 size_t allocation_bytes; 62 size_t allocation_bytes;
63 63
64 UnreachableMemoryInfo() {} 64 UnreachableMemoryInfo() {}
65 ~UnreachableMemoryInfo() { 65 ~UnreachableMemoryInfo();
66 // Clear the memory that holds the leaks, otherwise the next attempt to
67 // detect leaks may find the old data (for example in the jemalloc tcache)
68 // and consider all the leaks to be referenced.
69 memset(leaks.data(), 0, leaks.capacity() * sizeof(Leak));
70 }
71 66
72 std::string ToString(bool log_contents) const; 67 std::string ToString(bool log_contents) const;
73}; 68};
diff --git a/libmemunreachable/tests/MemUnreachable_test.cpp b/libmemunreachable/tests/MemUnreachable_test.cpp
index 87417f132..bba0c6d11 100644
--- a/libmemunreachable/tests/MemUnreachable_test.cpp
+++ b/libmemunreachable/tests/MemUnreachable_test.cpp
@@ -23,6 +23,8 @@
23 23
24#include <memunreachable/memunreachable.h> 24#include <memunreachable/memunreachable.h>
25 25
26#include "bionic.h"
27
26namespace android { 28namespace android {
27 29
28class HiddenPointer { 30class HiddenPointer {
@@ -48,7 +50,35 @@ static void Ref(void** ptr) {
48 write(0, ptr, 0); 50 write(0, ptr, 0);
49} 51}
50 52
51TEST(MemunreachableTest, clean) { 53class MemunreachableTest : public ::testing::Test {
54 protected:
55 virtual void SetUp() {
56 CleanStack(8192);
57 CleanTcache();
58 }
59
60 virtual void TearDown() {
61 CleanStack(8192);
62 CleanTcache();
63 }
64
65 // Allocate a buffer on the stack and zero it to make sure there are no
66 // stray pointers from old test runs.
67 void __attribute__((noinline)) CleanStack(size_t size) {
68 void* buf = alloca(size);
69 memset(buf, 0, size);
70 Ref(&buf);
71 }
72
73 // Disable and re-enable malloc to flush the jemalloc tcache to make sure
74 // there are stray pointers from old test runs there.
75 void CleanTcache() {
76 malloc_disable();
77 malloc_enable();
78 }
79};
80
81TEST_F(MemunreachableTest, clean) {
52 UnreachableMemoryInfo info; 82 UnreachableMemoryInfo info;
53 83
54 ASSERT_TRUE(LogUnreachableMemory(true, 100)); 84 ASSERT_TRUE(LogUnreachableMemory(true, 100));
@@ -57,7 +87,7 @@ TEST(MemunreachableTest, clean) {
57 ASSERT_EQ(0U, info.leaks.size()); 87 ASSERT_EQ(0U, info.leaks.size());
58} 88}
59 89
60TEST(MemunreachableTest, stack) { 90TEST_F(MemunreachableTest, stack) {
61 HiddenPointer hidden_ptr; 91 HiddenPointer hidden_ptr;
62 92
63 { 93 {
@@ -91,7 +121,7 @@ TEST(MemunreachableTest, stack) {
91 121
92void* g_ptr; 122void* g_ptr;
93 123
94TEST(MemunreachableTest, global) { 124TEST_F(MemunreachableTest, global) {
95 HiddenPointer hidden_ptr; 125 HiddenPointer hidden_ptr;
96 126
97 g_ptr = hidden_ptr.Get(); 127 g_ptr = hidden_ptr.Get();
@@ -122,7 +152,7 @@ TEST(MemunreachableTest, global) {
122 } 152 }
123} 153}
124 154
125TEST(MemunreachableTest, tls) { 155TEST_F(MemunreachableTest, tls) {
126 HiddenPointer hidden_ptr; 156 HiddenPointer hidden_ptr;
127 pthread_key_t key; 157 pthread_key_t key;
128 pthread_key_create(&key, nullptr); 158 pthread_key_create(&key, nullptr);
@@ -157,10 +187,22 @@ TEST(MemunreachableTest, tls) {
157 pthread_key_delete(key); 187 pthread_key_delete(key);
158} 188}
159 189
160TEST(MemunreachableTest, twice) { 190TEST_F(MemunreachableTest, twice) {
161 HiddenPointer hidden_ptr; 191 HiddenPointer hidden_ptr;
162 192
163 { 193 {
194 void* ptr = hidden_ptr.Get();
195 Ref(&ptr);
196
197 UnreachableMemoryInfo info;
198
199 ASSERT_TRUE(GetUnreachableMemory(info));
200 ASSERT_EQ(0U, info.leaks.size());
201
202 ptr = nullptr;
203 }
204
205 {
164 UnreachableMemoryInfo info; 206 UnreachableMemoryInfo info;
165 207
166 ASSERT_TRUE(GetUnreachableMemory(info)); 208 ASSERT_TRUE(GetUnreachableMemory(info));
@@ -184,7 +226,7 @@ TEST(MemunreachableTest, twice) {
184 } 226 }
185} 227}
186 228
187TEST(MemunreachableTest, log) { 229TEST_F(MemunreachableTest, log) {
188 HiddenPointer hidden_ptr; 230 HiddenPointer hidden_ptr;
189 231
190 ASSERT_TRUE(LogUnreachableMemory(true, 100)); 232 ASSERT_TRUE(LogUnreachableMemory(true, 100));
@@ -199,17 +241,23 @@ TEST(MemunreachableTest, log) {
199 } 241 }
200} 242}
201 243
202TEST(MemunreachableTest, notdumpable) { 244TEST_F(MemunreachableTest, notdumpable) {
245 if (getuid() == 0) {
246 // TODO(ccross): make this a skipped test when gtest supports them
247 printf("[ SKIP ] Not testable when running as root\n");
248 return;
249 }
250
203 ASSERT_EQ(0, prctl(PR_SET_DUMPABLE, 0)); 251 ASSERT_EQ(0, prctl(PR_SET_DUMPABLE, 0));
204 252
205 HiddenPointer hidden_ptr; 253 HiddenPointer hidden_ptr;
206 254
207 ASSERT_TRUE(LogUnreachableMemory(true, 100)); 255 EXPECT_FALSE(LogUnreachableMemory(true, 100));
208 256
209 ASSERT_EQ(0, prctl(PR_SET_DUMPABLE, 1)); 257 ASSERT_EQ(0, prctl(PR_SET_DUMPABLE, 1));
210} 258}
211 259
212TEST(MemunreachableTest, leak_lots) { 260TEST_F(MemunreachableTest, leak_lots) {
213 std::vector<HiddenPointer> hidden_ptrs; 261 std::vector<HiddenPointer> hidden_ptrs;
214 hidden_ptrs.resize(1024); 262 hidden_ptrs.resize(1024);
215 263