diff options
author | android-build-team Robot | 2018-05-16 02:22:42 -0500 |
---|---|---|
committer | android-build-team Robot | 2018-05-16 02:22:42 -0500 |
commit | 7c365bcc92616b3b672d47205c10ef9b33c7f0fd (patch) | |
tree | 081033e8febc079a34544441a62dbd99b87da1c5 | |
parent | 0ec0f4cb6ca15c7f54c22a885730fe33acfadd62 (diff) | |
parent | 05dca7ae962b2c9f7b038cea21cf318468a18404 (diff) | |
download | platform-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.cpp | 15 | ||||
-rw-r--r-- | libmemunreachable/include/memunreachable/memunreachable.h | 7 | ||||
-rw-r--r-- | libmemunreachable/tests/MemUnreachable_test.cpp | 66 |
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 | ||
498 | UnreachableMemoryInfo::~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 | |||
498 | std::string GetUnreachableMemoryString(bool log_contents, size_t limit) { | 513 | std::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 | |||
26 | namespace android { | 28 | namespace android { |
27 | 29 | ||
28 | class HiddenPointer { | 30 | class HiddenPointer { |
@@ -48,7 +50,35 @@ static void Ref(void** ptr) { | |||
48 | write(0, ptr, 0); | 50 | write(0, ptr, 0); |
49 | } | 51 | } |
50 | 52 | ||
51 | TEST(MemunreachableTest, clean) { | 53 | class 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 | |||
81 | TEST_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 | ||
60 | TEST(MemunreachableTest, stack) { | 90 | TEST_F(MemunreachableTest, stack) { |
61 | HiddenPointer hidden_ptr; | 91 | HiddenPointer hidden_ptr; |
62 | 92 | ||
63 | { | 93 | { |
@@ -91,7 +121,7 @@ TEST(MemunreachableTest, stack) { | |||
91 | 121 | ||
92 | void* g_ptr; | 122 | void* g_ptr; |
93 | 123 | ||
94 | TEST(MemunreachableTest, global) { | 124 | TEST_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 | ||
125 | TEST(MemunreachableTest, tls) { | 155 | TEST_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 | ||
160 | TEST(MemunreachableTest, twice) { | 190 | TEST_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 | ||
187 | TEST(MemunreachableTest, log) { | 229 | TEST_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 | ||
202 | TEST(MemunreachableTest, notdumpable) { | 244 | TEST_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 | ||
212 | TEST(MemunreachableTest, leak_lots) { | 260 | TEST_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 | ||