OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/trace_event/heap_profiler_allocation_register.h" | 5 #include "base/trace_event/heap_profiler_allocation_register.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 | 9 |
10 #include "base/process/process_metrics.h" | 10 #include "base/process/process_metrics.h" |
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
238 // Lookup should not find any garbage after removal. | 238 // Lookup should not find any garbage after removal. |
239 EXPECT_FALSE(reg.Get(reinterpret_cast<void*>(23), &a)); | 239 EXPECT_FALSE(reg.Get(reinterpret_cast<void*>(23), &a)); |
240 | 240 |
241 reg.Remove(reinterpret_cast<void*>(17)); | 241 reg.Remove(reinterpret_cast<void*>(17)); |
242 reg.Remove(reinterpret_cast<void*>(19)); | 242 reg.Remove(reinterpret_cast<void*>(19)); |
243 | 243 |
244 EXPECT_FALSE(reg.Get(reinterpret_cast<void*>(17), &a)); | 244 EXPECT_FALSE(reg.Get(reinterpret_cast<void*>(17), &a)); |
245 EXPECT_FALSE(reg.Get(reinterpret_cast<void*>(19), &a)); | 245 EXPECT_FALSE(reg.Get(reinterpret_cast<void*>(19), &a)); |
246 } | 246 } |
247 | 247 |
248 // Check that the process aborts due to hitting the guard page when inserting | 248 // Check that the table handles overflows of the allocation storage gracefully. |
249 // too many elements. | 249 TEST_F(AllocationRegisterTest, OverflowAllocationTest) { |
250 #if GTEST_HAS_DEATH_TEST | |
251 TEST_F(AllocationRegisterTest, OverflowDeathTest) { | |
252 const size_t allocation_capacity = GetAllocationCapacityPerPage(); | 250 const size_t allocation_capacity = GetAllocationCapacityPerPage(); |
253 AllocationRegister reg(allocation_capacity, kBacktraceCapacity); | 251 AllocationRegister reg(allocation_capacity, kBacktraceCapacity); |
254 AllocationContext ctx; | 252 AllocationContext ctx; |
255 size_t i; | 253 size_t i; |
256 | 254 |
257 // Fill up all of the memory allocated for the register's allocation map. | 255 for (int repetition = 0; repetition < 3; repetition++) { |
258 for (i = 0; i < allocation_capacity; i++) { | 256 // Fill up all of the memory allocated for the register's allocation map. |
259 reg.Insert(reinterpret_cast<void*>(i + 1), 1, ctx); | 257 for (i = 0; i < allocation_capacity; i++) |
| 258 ASSERT_TRUE(reg.Insert(reinterpret_cast<void*>(i + 1), 1, ctx)); |
| 259 |
| 260 // Adding just one extra element should cause overflow. |
| 261 ASSERT_FALSE(reg.Insert(reinterpret_cast<void*>(i + 1), 1, ctx)); |
| 262 |
| 263 // Removing all allocations shouldn't cause any crash. |
| 264 for (i = 0; i < allocation_capacity; i++) { |
| 265 reg.Remove(reinterpret_cast<void*>(i + 1)); |
| 266 } |
| 267 } |
| 268 } |
| 269 |
| 270 // Check that the table handles overflows of the backtrace storage (but not the |
| 271 // allocations storage) gracefully. |
| 272 TEST_F(AllocationRegisterTest, OverflowBacktraceTest) { |
| 273 const size_t backtrace_capacity = GetAllocationCapacityPerPage(); |
| 274 const size_t allocation_capacity = 3 * GetAllocationCapacityPerPage(); |
| 275 AllocationRegister reg(allocation_capacity, backtrace_capacity); |
| 276 AllocationContext ctx; |
| 277 size_t i; |
| 278 |
| 279 // Fill up all of the memory allocated for the backtrace allocation map, |
| 280 // but do not fill the allocations map. |
| 281 for (i = 1; i <= backtrace_capacity * 2; i++) { |
| 282 void* addr = reinterpret_cast<void*>(i); |
| 283 ctx.backtrace.frames[0] = StackFrame::FromProgramCounter(addr); |
| 284 ctx.backtrace.frame_count = 1; |
| 285 ASSERT_TRUE(reg.Insert(addr, 1, ctx)); |
260 } | 286 } |
261 | 287 |
262 // Adding just one extra element should cause overflow. | 288 // Removing all allocations shouldn't cause any crash. |
263 ASSERT_DEATH(reg.Insert(reinterpret_cast<void*>(i + 1), 1, ctx), ""); | 289 for (i = 1; i <= backtrace_capacity * 2; i++) { |
| 290 AllocationRegister::Allocation allocation = {}; |
| 291 ASSERT_TRUE(reg.Get(reinterpret_cast<void*>(i), &allocation)); |
| 292 |
| 293 // This is just to check the integrity of the backtrace sentinel and to make |
| 294 // sure that we don't hit the guard page. |
| 295 ASSERT_LT(allocation.context.backtrace.frame_count, |
| 296 static_cast<size_t>(Backtrace::kMaxFrameCount)); |
| 297 |
| 298 reg.Remove(reinterpret_cast<void*>(i)); |
| 299 } |
264 } | 300 } |
265 #endif | |
266 | 301 |
267 } // namespace trace_event | 302 } // namespace trace_event |
268 } // namespace base | 303 } // namespace base |
OLD | NEW |