stack_buffer_unittest.cc 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. // Copyright 2022 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "base/profiler/stack_buffer.h"
  5. #include "base/memory/aligned_memory.h"
  6. #include "build/build_config.h"
  7. #include "testing/gtest/include/gtest/gtest.h"
  8. #if BUILDFLAG(IS_CHROMEOS)
  9. #include "base/bits.h"
  10. #include "base/memory/page_size.h"
  11. #endif // #if BUILDFLAG(IS_CHROMEOS)
  12. namespace base {
  13. TEST(StackBufferTest, BufferAllocated) {
  14. const unsigned int kBufferSize = 32 * 1024;
  15. StackBuffer stack_buffer(kBufferSize);
  16. EXPECT_EQ(stack_buffer.size(), kBufferSize);
  17. // Without volatile, the compiler could simply optimize away the entire for
  18. // loop below.
  19. volatile uintptr_t* buffer = stack_buffer.buffer();
  20. ASSERT_NE(nullptr, buffer);
  21. EXPECT_TRUE(IsAligned(const_cast<uintptr_t*>(buffer),
  22. StackBuffer::kPlatformStackAlignment));
  23. // Memory pointed to by buffer should be writable.
  24. for (unsigned int i = 0; i < (kBufferSize / sizeof(buffer[0])); i++) {
  25. buffer[i] = i;
  26. EXPECT_EQ(buffer[i], i);
  27. }
  28. }
  29. #if BUILDFLAG(IS_CHROMEOS)
  30. TEST(StackBufferTest, MarkBufferContentsAsUnneeded) {
  31. const unsigned int kBufferSize = 32 * GetPageSize();
  32. StackBuffer stack_buffer(kBufferSize);
  33. volatile uintptr_t* buffer = stack_buffer.buffer();
  34. ASSERT_NE(nullptr, buffer);
  35. // Force the kernel to allocate backing store for the buffer.
  36. for (unsigned int i = 0; i < (kBufferSize / sizeof(uintptr_t)); i++) {
  37. buffer[i] = i;
  38. EXPECT_EQ(buffer[i], i);
  39. }
  40. // Tell kernel to discard (most of) the memory.
  41. constexpr size_t kUndiscardedElements = 100;
  42. stack_buffer.MarkUpperBufferContentsAsUnneeded(kUndiscardedElements *
  43. sizeof(buffer[0]));
  44. // The first 100 elements shouldn't have been discarded.
  45. for (size_t i = 0; i < kUndiscardedElements; i++) {
  46. EXPECT_EQ(buffer[i], i);
  47. }
  48. // Pages past the discard point should be zero-filled now.
  49. const size_t kExpectedDiscardStartPoint =
  50. bits::AlignUp(kUndiscardedElements * sizeof(buffer[0]), GetPageSize()) /
  51. sizeof(buffer[0]);
  52. for (size_t i = kExpectedDiscardStartPoint;
  53. i < kBufferSize / sizeof(buffer[0]); i++) {
  54. EXPECT_EQ(buffer[i], 0U);
  55. }
  56. // Writing to the memory (both discarded and undiscarded parts) shouldn't
  57. // cause segmentation faults and should remember the value we write.
  58. for (unsigned int i = 0; i < (kBufferSize / sizeof(buffer[0])); i++) {
  59. buffer[i] = i + 7;
  60. EXPECT_EQ(buffer[i], i + 7);
  61. }
  62. }
  63. #endif // #if BUILDFLAG(IS_CHROMEOS)
  64. } // namespace base