| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 #include "base/debug/gdi_debug_util_win.h" | 4 #include "base/debug/gdi_debug_util_win.h" |
| 5 | 5 |
| 6 #include <algorithm> |
| 6 #include <cmath> | 7 #include <cmath> |
| 7 | 8 |
| 8 #include <psapi.h> | 9 #include <psapi.h> |
| 9 #include <stddef.h> | 10 #include <stddef.h> |
| 10 #include <TlHelp32.h> | 11 #include <TlHelp32.h> |
| 11 | 12 |
| 12 #include "base/debug/alias.h" | 13 #include "base/debug/alias.h" |
| 13 #include "base/logging.h" | 14 #include "base/logging.h" |
| 14 #include "base/win/scoped_handle.h" | 15 #include "base/win/scoped_handle.h" |
| 15 #include "base/win/win_util.h" | 16 #include "base/win/win_util.h" |
| 16 | 17 |
| 17 namespace { | 18 namespace { |
| 18 | 19 |
| 19 void CollectChildGDIUsageAndDie(DWORD parent_pid) { | 20 void CollectChildGDIUsageAndDie(DWORD parent_pid) { |
| 20 HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); | 21 HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); |
| 21 CHECK_NE(INVALID_HANDLE_VALUE, snapshot); | 22 CHECK_NE(INVALID_HANDLE_VALUE, snapshot); |
| 22 | 23 |
| 24 int total_process_count = 0; |
| 25 base::debug::Alias(&total_process_count); |
| 26 int total_peak_gdi_count = 0; |
| 27 base::debug::Alias(&total_peak_gdi_count); |
| 28 int total_gdi_count = 0; |
| 29 base::debug::Alias(&total_gdi_count); |
| 30 int total_user_count = 0; |
| 31 base::debug::Alias(&total_user_count); |
| 32 |
| 23 int child_count = 0; | 33 int child_count = 0; |
| 24 base::debug::Alias(&child_count); | 34 base::debug::Alias(&child_count); |
| 25 int peak_gdi_count = 0; | 35 int peak_gdi_count = 0; |
| 26 base::debug::Alias(&peak_gdi_count); | 36 base::debug::Alias(&peak_gdi_count); |
| 27 int sum_gdi_count = 0; | 37 int sum_gdi_count = 0; |
| 28 base::debug::Alias(&sum_gdi_count); | 38 base::debug::Alias(&sum_gdi_count); |
| 29 int sum_user_count = 0; | 39 int sum_user_count = 0; |
| 30 base::debug::Alias(&sum_user_count); | 40 base::debug::Alias(&sum_user_count); |
| 31 | 41 |
| 32 PROCESSENTRY32 proc_entry = {0}; | 42 PROCESSENTRY32 proc_entry = {0}; |
| 33 proc_entry.dwSize = sizeof(PROCESSENTRY32); | 43 proc_entry.dwSize = sizeof(PROCESSENTRY32); |
| 34 CHECK(Process32First(snapshot, &proc_entry)); | 44 CHECK(Process32First(snapshot, &proc_entry)); |
| 35 | 45 |
| 36 do { | 46 do { |
| 37 if (parent_pid != proc_entry.th32ParentProcessID) | |
| 38 continue; | |
| 39 // Got a child process. Compute GDI usage. | |
| 40 base::win::ScopedHandle process( | 47 base::win::ScopedHandle process( |
| 41 OpenProcess(PROCESS_QUERY_INFORMATION, | 48 OpenProcess(PROCESS_QUERY_INFORMATION, |
| 42 FALSE, | 49 FALSE, |
| 43 proc_entry.th32ProcessID)); | 50 proc_entry.th32ProcessID)); |
| 44 if (!process.IsValid()) | 51 if (!process.IsValid()) |
| 45 continue; | 52 continue; |
| 46 | 53 |
| 47 int num_gdi_handles = GetGuiResources(process.Get(), GR_GDIOBJECTS); | 54 int num_gdi_handles = GetGuiResources(process.Get(), GR_GDIOBJECTS); |
| 48 int num_user_handles = GetGuiResources(process.Get(), GR_USEROBJECTS); | 55 int num_user_handles = GetGuiResources(process.Get(), GR_USEROBJECTS); |
| 49 | 56 |
| 50 // Compute sum and peak counts. | 57 // Compute sum and peak counts for all processes. |
| 58 ++total_process_count; |
| 59 total_user_count += num_user_handles; |
| 60 total_gdi_count += num_gdi_handles; |
| 61 total_peak_gdi_count = std::max(total_peak_gdi_count, num_gdi_handles); |
| 62 |
| 63 if (parent_pid != proc_entry.th32ParentProcessID) |
| 64 continue; |
| 65 |
| 66 // Compute sum and peak counts for child processes. |
| 51 ++child_count; | 67 ++child_count; |
| 52 sum_user_count += num_user_handles; | 68 sum_user_count += num_user_handles; |
| 53 sum_gdi_count += num_gdi_handles; | 69 sum_gdi_count += num_gdi_handles; |
| 54 if (peak_gdi_count < num_gdi_handles) | 70 peak_gdi_count = std::max(peak_gdi_count, num_gdi_handles); |
| 55 peak_gdi_count = num_gdi_handles; | |
| 56 | 71 |
| 57 } while (Process32Next(snapshot, &proc_entry)); | 72 } while (Process32Next(snapshot, &proc_entry)); |
| 58 | 73 |
| 59 CloseHandle(snapshot); | 74 CloseHandle(snapshot); |
| 60 CHECK(false); | 75 CHECK(false); |
| 61 } | 76 } |
| 62 | 77 |
| 63 } // namespace | 78 } // namespace |
| 64 | 79 |
| 65 namespace base { | 80 namespace base { |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 117 0, &small_data, shared_section, 0); | 132 0, &small_data, shared_section, 0); |
| 118 CHECK(small_bitmap != nullptr); | 133 CHECK(small_bitmap != nullptr); |
| 119 DeleteObject(small_bitmap); | 134 DeleteObject(small_bitmap); |
| 120 } | 135 } |
| 121 // Maybe the child processes are the ones leaking GDI or USER resouces. | 136 // Maybe the child processes are the ones leaking GDI or USER resouces. |
| 122 CollectChildGDIUsageAndDie(GetCurrentProcessId()); | 137 CollectChildGDIUsageAndDie(GetCurrentProcessId()); |
| 123 } | 138 } |
| 124 | 139 |
| 125 } // namespace debug | 140 } // namespace debug |
| 126 } // namespace base | 141 } // namespace base |
| OLD | NEW |