OLD | NEW |
---|---|
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 <execinfo.h> | |
Cutch
2017/02/08 00:28:54
This is a cross platform test file. backtrace/exec
bkonyi
2017/02/08 01:37:05
This was more here for me to check that my impleme
zra
2017/02/08 17:42:55
Not sure how portable this is. Should this be gate
bkonyi
2017/02/09 21:22:46
Yes, it probably should. However, DART_USE_TCMALLO
| |
10 | |
9 #include "platform/assert.h" | 11 #include "platform/assert.h" |
10 #include "vm/class_finalizer.h" | 12 #include "vm/class_finalizer.h" |
11 #include "vm/globals.h" | 13 #include "vm/globals.h" |
12 #include "vm/malloc_hooks.h" | 14 #include "vm/malloc_hooks.h" |
15 #include "vm/native_symbol.h" | |
16 #include "vm/profiler.h" | |
13 #include "vm/symbols.h" | 17 #include "vm/symbols.h" |
14 #include "vm/unit_test.h" | 18 #include "vm/unit_test.h" |
15 | 19 |
16 namespace dart { | 20 namespace dart { |
17 | 21 |
18 static void MallocHookTestBufferInitializer(volatile char* buffer, | 22 static void MallocHookTestBufferInitializer(volatile char* buffer, |
19 uintptr_t size) { | 23 uintptr_t size) { |
20 // Run through the buffer and do something. If we don't do this and the memory | 24 // 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. | 25 // in buffer isn't touched, the tcmalloc hooks won't be called. |
22 for (uintptr_t i = 0; i < size; ++i) { | 26 for (uintptr_t i = 0; i < size; ++i) { |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
68 EXPECT_EQ(static_cast<intptr_t>(sizeof(char) * buffer_size), | 72 EXPECT_EQ(static_cast<intptr_t>(sizeof(char) * buffer_size), |
69 MallocHooks::heap_allocated_memory_in_bytes()); | 73 MallocHooks::heap_allocated_memory_in_bytes()); |
70 | 74 |
71 | 75 |
72 delete[] buffer; | 76 delete[] buffer; |
73 EXPECT_EQ(0L, MallocHooks::allocation_count()); | 77 EXPECT_EQ(0L, MallocHooks::allocation_count()); |
74 EXPECT_EQ(0L, MallocHooks::heap_allocated_memory_in_bytes()); | 78 EXPECT_EQ(0L, MallocHooks::heap_allocated_memory_in_bytes()); |
75 MallocHooks::TearDown(); | 79 MallocHooks::TearDown(); |
76 } | 80 } |
77 | 81 |
82 // Helper used to add another frame to the stack before allocating. | |
83 char* AllocationHelper(void* stack_trace[32]) { | |
84 backtrace(stack_trace, 32); | |
85 return static_cast<char*>(malloc(16 * sizeof(char))); | |
86 } | |
87 | |
88 VM_UNIT_TEST_CASE(StackTraceMallocHookTest) { | |
89 MallocHooks::ResetStats(); | |
90 ASSERT(OSThread::DoesCurrentThreadExist()); | |
91 | |
92 const intptr_t first_frame_count = 6; | |
93 void* stack_trace[32]; | |
94 | |
95 // Perform the memory allocation and grab the stack trace created by | |
96 // backtrace() for comparison purposes. | |
97 char* var = AllocationHelper(stack_trace); | |
98 | |
99 // Update top pc of the stack trace to match the location that malloc was | |
100 // called in AllocationHelper. The rest of the pcs should match without any | |
101 // changes. | |
102 stack_trace[0] = | |
103 reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(stack_trace[0]) + 15); | |
104 | |
105 Sample* sample = MallocHooks::GetSample(var); | |
106 ASSERT(sample != NULL); | |
107 | |
108 intptr_t frame_count = 0; | |
109 while (sample != NULL) { | |
Cutch
2017/02/08 00:28:53
This test might not be necessary. We have tests wh
bkonyi
2017/02/08 01:37:05
Makes sense. I'll remove it before actually landin
| |
110 for (uintptr_t i = 0; i < 8; ++i) { | |
111 // Cease comparisons after we pass the frame for main. | |
112 if (sample->At(i) == 0) { | |
113 break; | |
114 } | |
115 | |
116 // The first 6 frames in the stack trace we generate are all from the | |
117 // memory allocation. The frame for AllocationHelper is the 7th element, | |
118 // so we skip checking all the frames before that. | |
119 if (frame_count >= first_frame_count) { | |
120 EXPECT_EQ(reinterpret_cast<uword>( | |
121 stack_trace[frame_count - first_frame_count]), | |
122 sample->At(i)); | |
123 } | |
124 ++frame_count; | |
125 } | |
126 | |
127 if (!sample->is_continuation_sample()) { | |
128 break; | |
129 } | |
130 sample = Profiler::sample_buffer()->At(sample->continuation_index()); | |
131 } | |
132 } | |
133 | |
78 }; // namespace dart | 134 }; // namespace dart |
79 | 135 |
80 #endif // defined(DART_USE_TCMALLOC) && !defined(PRODUCT) | 136 #endif // defined(DART_USE_TCMALLOC) && !defined(PRODUCT) |
OLD | NEW |