Chromium Code Reviews| 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/winheap_dump_provider_win.h" | 5 #include "base/trace_event/winheap_dump_provider_win.h" |
| 6 | 6 |
| 7 #include <windows.h> | 7 #include <windows.h> |
| 8 | 8 |
| 9 #include "base/debug/profiler.h" | 9 #include "base/debug/profiler.h" |
| 10 #include "base/strings/string_util.h" | 10 #include "base/strings/string_util.h" |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 79 | 79 |
| 80 // Skip the pointer to the heap array to avoid accounting the memory used by | 80 // Skip the pointer to the heap array to avoid accounting the memory used by |
| 81 // this dump provider. | 81 // this dump provider. |
| 82 std::set<void*> block_to_skip; | 82 std::set<void*> block_to_skip; |
| 83 block_to_skip.insert(all_heaps.get()); | 83 block_to_skip.insert(all_heaps.get()); |
| 84 | 84 |
| 85 // Retrieves some metrics about each heap. | 85 // Retrieves some metrics about each heap. |
| 86 for (size_t i = 0; i < number_of_heaps; ++i) { | 86 for (size_t i = 0; i < number_of_heaps; ++i) { |
| 87 WinHeapInfo heap_info = {0}; | 87 WinHeapInfo heap_info = {0}; |
| 88 heap_info.heap_id = all_heaps[i]; | 88 heap_info.heap_id = all_heaps[i]; |
| 89 GetHeapInformation(&heap_info, block_to_skip); | |
| 90 | 89 |
| 91 all_heap_info.allocated_size += heap_info.allocated_size; | 90 if (GetHeapInformation(&heap_info, block_to_skip)) { |
| 92 all_heap_info.committed_size += heap_info.committed_size; | 91 all_heap_info.allocated_size += heap_info.allocated_size; |
| 93 all_heap_info.block_count += heap_info.block_count; | 92 all_heap_info.committed_size += heap_info.committed_size; |
| 93 all_heap_info.block_count += heap_info.block_count; | |
| 94 } | |
| 94 } | 95 } |
| 96 CHECK(all_heap_info.allocated_size != 0); | |
|
danakj
2016/08/15 23:42:03
CHECK_NE will give better failure output
liamjm (20p)
2016/10/11 18:57:31
Done.
| |
| 95 // Report the heap dump. | 97 // Report the heap dump. |
| 96 ReportHeapDump(pmd, all_heap_info); | 98 ReportHeapDump(pmd, all_heap_info); |
| 97 return true; | 99 return true; |
| 98 } | 100 } |
| 99 | 101 |
| 100 bool WinHeapDumpProvider::GetHeapInformation( | 102 bool WinHeapDumpProvider::GetHeapInformation( |
| 101 WinHeapInfo* heap_info, | 103 WinHeapInfo* heap_info, |
| 102 const std::set<void*>& block_to_skip) { | 104 const std::set<void*>& block_to_skip) { |
| 103 CHECK(::HeapLock(heap_info->heap_id) == TRUE); | 105 // NOTE: bug 464430 |
|
danakj
2016/08/15 23:42:03
nit: crbug.com/464430
liamjm (20p)
2016/10/11 18:57:30
Done.
| |
| 106 // As a part of the CSRSS lockdown in the referenced bug, it will invalidate | |
|
danakj
2016/08/15 23:42:03
Please explain/write out what CSRSS is here, acron
liamjm (20p)
2016/10/11 18:57:31
Done.
| |
| 107 // the heap used by CSRSS. As there is no documented way to clean this up, | |
| 108 // we test the handle first. As the HEAP struct is not documented, we select | |
| 109 // a sane value of bytes to check. | |
| 110 // There are reasons not to use IsBadReadPtr | |
| 111 // (https://msdn.microsoft.com/en-us/library/aa366713(VS.85).aspx) | |
| 112 // however as we are testing if the memory is already unreadable, these | |
| 113 // reasons are not relevant. | |
| 114 if (::IsBadReadPtr(heap_info->heap_id, 0x100)) { | |
|
danakj
2016/08/15 23:42:03
How confident are you that 0x100 is a good size? W
danakj
2016/08/15 23:43:51
Also it's not clear to me after reading your patch
liamjm (20p)
2016/10/11 18:57:31
Obsolete as this code has been removed.
liamjm (20p)
2016/10/11 18:57:31
Yes this using this function is racey. The idea wa
| |
| 115 return false; | |
| 116 } | |
| 117 // This is implicitly checks certain aspects of the HEAP structure, such as | |
|
danakj
2016/08/15 23:43:51
nit: This implicitly checks
liamjm (20p)
2016/10/11 18:57:31
Done.
| |
| 118 // the signature. If this passes, we assume that this heap is valid and is | |
| 119 // not the one owned by CSRSS. | |
| 120 if (!::HeapLock(heap_info->heap_id)) { | |
| 121 return false; | |
| 122 } | |
| 123 | |
| 104 PROCESS_HEAP_ENTRY heap_entry; | 124 PROCESS_HEAP_ENTRY heap_entry; |
| 105 heap_entry.lpData = nullptr; | 125 heap_entry.lpData = nullptr; |
| 106 // Walk over all the entries in this heap. | 126 // Walk over all the entries in this heap. |
| 107 while (::HeapWalk(heap_info->heap_id, &heap_entry) != FALSE) { | 127 while (::HeapWalk(heap_info->heap_id, &heap_entry) != FALSE) { |
| 108 if (block_to_skip.count(heap_entry.lpData) == 1) | 128 if (block_to_skip.count(heap_entry.lpData) == 1) |
| 109 continue; | 129 continue; |
| 110 if ((heap_entry.wFlags & PROCESS_HEAP_ENTRY_BUSY) != 0) { | 130 if ((heap_entry.wFlags & PROCESS_HEAP_ENTRY_BUSY) != 0) { |
| 111 heap_info->allocated_size += heap_entry.cbData; | 131 heap_info->allocated_size += heap_entry.cbData; |
| 112 heap_info->block_count++; | 132 heap_info->block_count++; |
| 113 } else if ((heap_entry.wFlags & PROCESS_HEAP_REGION) != 0) { | 133 } else if ((heap_entry.wFlags & PROCESS_HEAP_REGION) != 0) { |
| 114 heap_info->committed_size += heap_entry.Region.dwCommittedSize; | 134 heap_info->committed_size += heap_entry.Region.dwCommittedSize; |
| 115 } | 135 } |
| 116 } | 136 } |
| 117 CHECK(::HeapUnlock(heap_info->heap_id) == TRUE); | 137 CHECK(::HeapUnlock(heap_info->heap_id) == TRUE); |
| 118 return true; | 138 return true; |
| 119 } | 139 } |
| 120 | 140 |
| 121 } // namespace trace_event | 141 } // namespace trace_event |
| 122 } // namespace base | 142 } // namespace base |
| OLD | NEW |