Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(28)

Side by Side Diff: runtime/vm/malloc_hooks_test.cc

Issue 2680213002: Updated MallocHooks to collect stack traces when memory is allocated. (Closed)
Patch Set: Updated MallocHooks to collect stack traces when memory is allocated. Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "platform/globals.h" 5 #include "platform/globals.h"
6 6
7 #if defined(DART_USE_TCMALLOC) && !defined(PRODUCT) 7 #if defined(DART_USE_TCMALLOC) && !defined(PRODUCT)
8 8
9 #include "platform/assert.h" 9 #include "platform/assert.h"
10 #include "vm/class_finalizer.h"
11 #include "vm/globals.h" 10 #include "vm/globals.h"
12 #include "vm/malloc_hooks.h" 11 #include "vm/malloc_hooks.h"
13 #include "vm/symbols.h" 12 #include "vm/os.h"
13 #include "vm/profiler.h"
14 #include "vm/profiler_service.h"
14 #include "vm/unit_test.h" 15 #include "vm/unit_test.h"
15 16
16 namespace dart { 17 namespace dart {
17 18
18 static void MallocHookTestBufferInitializer(volatile char* buffer, 19 static void MallocHookTestBufferInitializer(volatile char* buffer,
19 uintptr_t size) { 20 uintptr_t size) {
20 // Run through the buffer and do something. If we don't do this and the memory 21 // Run through the buffer and do something. If we don't do this and the memory
21 // in buffer isn't touched, the tcmalloc hooks won't be called. 22 // in buffer isn't touched, the tcmalloc hooks won't be called.
22 for (uintptr_t i = 0; i < size; ++i) { 23 for (uintptr_t i = 0; i < size; ++i) {
23 buffer[i] = i; 24 buffer[i] = i;
(...skipping 25 matching lines...) Expand all
49 MallocHooks::InitOnce(); 50 MallocHooks::InitOnce();
50 const intptr_t pre_hook_buffer_size = 3; 51 const intptr_t pre_hook_buffer_size = 3;
51 char* pre_hook_buffer = new char[pre_hook_buffer_size]; 52 char* pre_hook_buffer = new char[pre_hook_buffer_size];
52 MallocHookTestBufferInitializer(pre_hook_buffer, pre_hook_buffer_size); 53 MallocHookTestBufferInitializer(pre_hook_buffer, pre_hook_buffer_size);
53 54
54 MallocHooks::ResetStats(); 55 MallocHooks::ResetStats();
55 EXPECT_EQ(0L, MallocHooks::allocation_count()); 56 EXPECT_EQ(0L, MallocHooks::allocation_count());
56 EXPECT_EQ(0L, MallocHooks::heap_allocated_memory_in_bytes()); 57 EXPECT_EQ(0L, MallocHooks::heap_allocated_memory_in_bytes());
57 58
58 const intptr_t buffer_size = 10; 59 const intptr_t buffer_size = 10;
59 volatile char* buffer = new char[buffer_size]; 60 char* buffer = new char[buffer_size];
60 MallocHookTestBufferInitializer(buffer, buffer_size); 61 MallocHookTestBufferInitializer(buffer, buffer_size);
61 62
62 EXPECT_EQ(1L, MallocHooks::allocation_count()); 63 EXPECT_EQ(1L, MallocHooks::allocation_count());
63 EXPECT_EQ(static_cast<intptr_t>(sizeof(char) * buffer_size), 64 EXPECT_EQ(static_cast<intptr_t>(sizeof(char) * buffer_size),
64 MallocHooks::heap_allocated_memory_in_bytes()); 65 MallocHooks::heap_allocated_memory_in_bytes());
65 66
66 delete[] pre_hook_buffer; 67 delete[] pre_hook_buffer;
67 EXPECT_EQ(1L, MallocHooks::allocation_count()); 68 EXPECT_EQ(1L, MallocHooks::allocation_count());
68 EXPECT_EQ(static_cast<intptr_t>(sizeof(char) * buffer_size), 69 EXPECT_EQ(static_cast<intptr_t>(sizeof(char) * buffer_size),
69 MallocHooks::heap_allocated_memory_in_bytes()); 70 MallocHooks::heap_allocated_memory_in_bytes());
70 71
71 72
72 delete[] buffer; 73 delete[] buffer;
73 EXPECT_EQ(0L, MallocHooks::allocation_count()); 74 EXPECT_EQ(0L, MallocHooks::allocation_count());
74 EXPECT_EQ(0L, MallocHooks::heap_allocated_memory_in_bytes()); 75 EXPECT_EQ(0L, MallocHooks::heap_allocated_memory_in_bytes());
75 MallocHooks::TearDown(); 76 MallocHooks::TearDown();
76 } 77 }
77 78
79
80 VM_UNIT_TEST_CASE(StackTraceMallocHookSimpleTest) {
81 MallocHooks::ResetStats();
82 ASSERT(MallocHooks::ProfilingEnabled());
83
84 char* var = static_cast<char*>(malloc(16 * sizeof(char)));
85 Sample* sample = MallocHooks::GetSample(var);
86 EXPECT(sample != NULL);
87
88 free(var);
89 sample = MallocHooks::GetSample(var);
90 EXPECT(sample == NULL);
91 }
92
93
94 static char* DART_NOINLINE StackTraceLengthHelper(uintptr_t* end_address) {
95 char* var = static_cast<char*>(malloc(16 * sizeof(char)));
96 *end_address = OS::GetProgramCounter();
97 return var;
98 }
99
100
101 VM_UNIT_TEST_CASE(StackTraceMallocHookLengthTest) {
102 uintptr_t test_start_address =
103 reinterpret_cast<uintptr_t>(Dart_TestStackTraceMallocHookLengthTest);
104 uintptr_t helper_start_address =
105 reinterpret_cast<uintptr_t>(StackTraceLengthHelper);
106 uintptr_t helper_end_address = 0;
107
108 MallocHooks::ResetStats();
109 ASSERT(MallocHooks::ProfilingEnabled());
110
111 char* var = StackTraceLengthHelper(&helper_end_address);
112 Sample* sample = MallocHooks::GetSample(var);
113 EXPECT(sample != NULL);
114 uintptr_t test_end_address = OS::GetProgramCounter();
115
116 // Ensure that all stack frames are where we expect them to be in the sample.
117 // If they aren't, the kSkipCount constant in malloc_hooks.cc is likely
118 // incorrect.
119 uword address = sample->At(0);
120 bool first_result =
121 (helper_start_address <= address) && (helper_end_address >= address);
122 EXPECT(first_result);
123 address = sample->At(1);
124 bool second_result =
125 (test_start_address <= address) && (test_end_address >= address);
126 EXPECT(second_result);
127
128 if (!(first_result && second_result)) {
129 OS::PrintErr(
130 "If this test is failing, it's likely that the value set for"
131 "the number of frames to skip in malloc_hooks.cc is "
132 "incorrect for this configuration/platform. This value can be"
133 " found in malloc_hooks.cc in the AllocationInfo class, and "
134 "is stored in the kSkipCount constant.");
135 }
136
137 free(var);
138 }
139
140
141 ISOLATE_UNIT_TEST_CASE(StackTraceMallocHookSimpleJSONTest) {
142 MallocHooks::ResetStats();
143 ASSERT(MallocHooks::ProfilingEnabled());
144 ClearProfileVisitor cpv(Isolate::Current());
145 Profiler::sample_buffer()->VisitSamples(&cpv);
146
147 char* var = static_cast<char*>(malloc(16 * sizeof(char)));
148 JSONStream js;
149 ProfilerService::PrintNativeAllocationJSON(&js, Profile::kNoTags, -1, -1);
150 const char* json = js.ToCString();
151
152 // Check that all the stack frames from the current down to main are actually
153 // present in the profile. This is just a simple sanity check to make sure
154 // that the ProfileTrie has a representation of the stack trace collected when
155 // var is allocated. More intense testing is already done in profiler_test.cc.
156 EXPECT_SUBSTRING("\"dart::Dart_TestStackTraceMallocHookSimpleJSONTest()\"",
157 json);
158 EXPECT_SUBSTRING("\"dart::TestCase::Run()\"", json);
159 EXPECT_SUBSTRING("\"dart::TestCaseBase::RunTest()\"", json);
160 EXPECT_SUBSTRING("\"main\"", json);
161
162 free(var);
163 }
164
78 }; // namespace dart 165 }; // namespace dart
79 166
80 #endif // defined(DART_USE_TCMALLOC) && !defined(PRODUCT) 167 #endif // defined(DART_USE_TCMALLOC) && !defined(PRODUCT)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698