Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "chrome/browser/memory_details.h" | 5 #include "chrome/browser/memory_details.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <sys/types.h> | 8 #include <sys/types.h> |
| 9 #include <unistd.h> | 9 #include <unistd.h> |
| 10 | 10 |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 24 #include "chrome/grit/chromium_strings.h" | 24 #include "chrome/grit/chromium_strings.h" |
| 25 #include "content/public/browser/browser_thread.h" | 25 #include "content/public/browser/browser_thread.h" |
| 26 #include "content/public/common/process_type.h" | 26 #include "content/public/common/process_type.h" |
| 27 #include "ui/base/l10n/l10n_util.h" | 27 #include "ui/base/l10n/l10n_util.h" |
| 28 | 28 |
| 29 using base::ProcessEntry; | 29 using base::ProcessEntry; |
| 30 using content::BrowserThread; | 30 using content::BrowserThread; |
| 31 | 31 |
| 32 namespace { | 32 namespace { |
| 33 | 33 |
| 34 // Known browsers which we collect details for. | |
| 35 enum BrowserType { | |
| 36 CHROME = 0, | |
| 37 FIREFOX, | |
| 38 ICEWEASEL, | |
| 39 OPERA, | |
| 40 KONQUEROR, | |
| 41 EPIPHANY, | |
| 42 MIDORI, | |
| 43 MAX_BROWSERS | |
| 44 }; | |
| 45 | |
| 46 // The pretty printed names of those browsers. Matches up with enum | |
| 47 // BrowserType. | |
| 48 const char kBrowserPrettyNames[][10] = { | |
| 49 "Chrome", | |
| 50 "Firefox", | |
| 51 "Iceweasel", | |
| 52 "Opera", | |
| 53 "Konqueror", | |
| 54 "Epiphany", | |
| 55 "Midori", | |
| 56 }; | |
| 57 | |
| 58 // A mapping from process name to the type of browser. | |
| 59 const struct { | |
| 60 const char process_name[17]; | |
| 61 BrowserType browser; | |
| 62 } kBrowserBinaryNames[] = { | |
| 63 { "firefox", FIREFOX }, | |
| 64 { "firefox-3.5", FIREFOX }, | |
| 65 { "firefox-3.0", FIREFOX }, | |
| 66 { "firefox-bin", FIREFOX }, | |
| 67 { "iceweasel", ICEWEASEL }, | |
| 68 { "opera", OPERA }, | |
| 69 { "konqueror", KONQUEROR }, | |
| 70 { "epiphany-browser", EPIPHANY }, | |
| 71 { "epiphany", EPIPHANY }, | |
| 72 { "midori", MIDORI }, | |
| 73 { "", MAX_BROWSERS }, | |
| 74 }; | |
| 75 | |
| 76 struct Process { | 34 struct Process { |
| 77 pid_t pid; | 35 pid_t pid; |
| 78 pid_t parent; | 36 pid_t parent; |
| 79 std::string name; | |
| 80 }; | 37 }; |
| 81 | 38 |
| 82 typedef std::map<pid_t, Process> ProcessMap; | 39 typedef std::map<pid_t, Process> ProcessMap; |
| 83 | 40 |
| 84 // Get information on all the processes running on the system. | 41 // Get information on all the processes running on the system. |
| 85 ProcessMap GetProcesses() { | 42 ProcessMap GetProcesses() { |
| 86 ProcessMap map; | 43 ProcessMap map; |
| 87 | 44 |
| 88 base::ProcessIterator process_iter(NULL); | 45 base::ProcessIterator process_iter(NULL); |
| 89 while (const ProcessEntry* process_entry = process_iter.NextProcessEntry()) { | 46 while (const ProcessEntry* process_entry = process_iter.NextProcessEntry()) { |
| 90 Process process; | 47 Process process; |
| 91 process.pid = process_entry->pid(); | 48 process.pid = process_entry->pid(); |
| 92 process.parent = process_entry->parent_pid(); | 49 process.parent = process_entry->parent_pid(); |
| 93 process.name = process_entry->exe_file(); | |
| 94 map.insert(std::make_pair(process.pid, process)); | 50 map.insert(std::make_pair(process.pid, process)); |
| 95 } | 51 } |
| 96 return map; | 52 return map; |
| 97 } | 53 } |
| 98 | 54 |
| 99 // Given a process name, return the type of the browser which created that | |
| 100 // process, or |MAX_BROWSERS| if we don't know about it. | |
| 101 BrowserType GetBrowserType(const std::string& process_name) { | |
| 102 for (unsigned i = 0; kBrowserBinaryNames[i].process_name[0]; ++i) { | |
| 103 if (strcmp(process_name.c_str(), kBrowserBinaryNames[i].process_name) == 0) | |
| 104 return kBrowserBinaryNames[i].browser; | |
| 105 } | |
| 106 | |
| 107 return MAX_BROWSERS; | |
| 108 } | |
| 109 | |
| 110 // For each of a list of pids, collect memory information about that process. | 55 // For each of a list of pids, collect memory information about that process. |
| 111 ProcessData GetProcessDataMemoryInformation( | 56 ProcessData GetProcessDataMemoryInformation( |
| 112 const std::vector<pid_t>& pids) { | 57 const std::vector<pid_t>& pids) { |
| 113 ProcessData process_data; | 58 ProcessData process_data; |
| 114 for (pid_t pid : pids) { | 59 for (pid_t pid : pids) { |
| 115 ProcessMemoryInformation pmi; | 60 ProcessMemoryInformation pmi; |
| 116 | 61 |
| 117 pmi.pid = pid; | 62 pmi.pid = pid; |
| 118 pmi.num_processes = 1; | 63 pmi.num_processes = 1; |
| 119 | 64 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 157 } // namespace | 102 } // namespace |
| 158 | 103 |
| 159 MemoryDetails::MemoryDetails() { | 104 MemoryDetails::MemoryDetails() { |
| 160 } | 105 } |
| 161 | 106 |
| 162 ProcessData* MemoryDetails::ChromeBrowser() { | 107 ProcessData* MemoryDetails::ChromeBrowser() { |
| 163 return &process_data_[0]; | 108 return &process_data_[0]; |
| 164 } | 109 } |
| 165 | 110 |
| 166 void MemoryDetails::CollectProcessData( | 111 void MemoryDetails::CollectProcessData( |
| 167 CollectionMode mode, | |
| 168 const std::vector<ProcessMemoryInformation>& child_info) { | 112 const std::vector<ProcessMemoryInformation>& child_info) { |
| 169 DCHECK(BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread()); | 113 DCHECK(BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread()); |
| 170 | 114 |
| 171 ProcessMap process_map = GetProcesses(); | 115 ProcessMap process_map = GetProcesses(); |
| 172 std::set<pid_t> browsers_found; | 116 std::set<pid_t> browsers_found; |
|
Alexei Svitkine (slow)
2016/04/13 19:17:52
Nit: Remove?
| |
| 173 | 117 |
| 174 // For each process on the system, if it appears to be a browser process and | |
| 175 // it's parent isn't a browser process, then record it in |browsers_found|. | |
| 176 for (const auto& entry : process_map) { | |
| 177 const Process& current_process = entry.second; | |
| 178 const BrowserType type = GetBrowserType(current_process.name); | |
| 179 if (type == MAX_BROWSERS) | |
| 180 continue; | |
| 181 if (type != CHROME && mode == FROM_CHROME_ONLY) | |
| 182 continue; | |
| 183 | |
| 184 ProcessMap::const_iterator parent_iter = | |
| 185 process_map.find(current_process.parent); | |
| 186 if (parent_iter == process_map.end()) { | |
| 187 browsers_found.insert(current_process.pid); | |
| 188 continue; | |
| 189 } | |
| 190 | |
| 191 if (GetBrowserType(parent_iter->second.name) != type) { | |
| 192 // We found a process whose type is different from its parent's type. | |
| 193 // That means it is the root process of the browser. | |
| 194 browsers_found.insert(current_process.pid); | |
| 195 continue; | |
| 196 } | |
| 197 } | |
| 198 | |
| 199 ProcessData current_browser = | 118 ProcessData current_browser = |
| 200 GetProcessDataMemoryInformation(GetAllChildren(process_map, getpid())); | 119 GetProcessDataMemoryInformation(GetAllChildren(process_map, getpid())); |
| 201 current_browser.name = l10n_util::GetStringUTF16(IDS_SHORT_PRODUCT_NAME); | 120 current_browser.name = l10n_util::GetStringUTF16(IDS_SHORT_PRODUCT_NAME); |
| 202 current_browser.process_name = base::ASCIIToUTF16("chrome"); | 121 current_browser.process_name = base::ASCIIToUTF16("chrome"); |
| 203 | 122 |
| 204 for (std::vector<ProcessMemoryInformation>::iterator | 123 for (std::vector<ProcessMemoryInformation>::iterator |
| 205 i = current_browser.processes.begin(); | 124 i = current_browser.processes.begin(); |
| 206 i != current_browser.processes.end(); ++i) { | 125 i != current_browser.processes.end(); ++i) { |
| 207 // Check if this is one of the child processes whose data we collected | 126 // Check if this is one of the child processes whose data we collected |
| 208 // on the IO thread, and if so copy over that data. | 127 // on the IO thread, and if so copy over that data. |
| 209 for (size_t child = 0; child < child_info.size(); child++) { | 128 for (size_t child = 0; child < child_info.size(); child++) { |
| 210 if (child_info[child].pid != i->pid) | 129 if (child_info[child].pid != i->pid) |
| 211 continue; | 130 continue; |
| 212 i->titles = child_info[child].titles; | 131 i->titles = child_info[child].titles; |
| 213 i->process_type = child_info[child].process_type; | 132 i->process_type = child_info[child].process_type; |
| 214 break; | 133 break; |
| 215 } | 134 } |
| 216 } | 135 } |
| 217 | 136 |
| 218 process_data_.push_back(current_browser); | 137 process_data_.push_back(current_browser); |
| 219 | 138 |
| 220 // For each browser process, collect a list of its children and get the | |
| 221 // memory usage of each. | |
| 222 for (pid_t pid : browsers_found) { | |
| 223 std::vector<pid_t> browser_processes = GetAllChildren(process_map, pid); | |
| 224 ProcessData browser = GetProcessDataMemoryInformation(browser_processes); | |
| 225 | |
| 226 ProcessMap::const_iterator process_iter = process_map.find(pid); | |
| 227 if (process_iter == process_map.end()) | |
| 228 continue; | |
| 229 BrowserType type = GetBrowserType(process_iter->second.name); | |
| 230 if (type != MAX_BROWSERS) | |
| 231 browser.name = base::ASCIIToUTF16(kBrowserPrettyNames[type]); | |
| 232 process_data_.push_back(browser); | |
| 233 } | |
| 234 | |
| 235 #if defined(OS_CHROMEOS) | 139 #if defined(OS_CHROMEOS) |
| 236 base::GetSwapInfo(&swap_info_); | 140 base::GetSwapInfo(&swap_info_); |
| 237 #endif | 141 #endif |
| 238 | 142 |
| 239 // Finally return to the browser thread. | 143 // Finally return to the browser thread. |
| 240 BrowserThread::PostTask( | 144 BrowserThread::PostTask( |
| 241 BrowserThread::UI, FROM_HERE, | 145 BrowserThread::UI, FROM_HERE, |
| 242 base::Bind(&MemoryDetails::CollectChildInfoOnUIThread, this)); | 146 base::Bind(&MemoryDetails::CollectChildInfoOnUIThread, this)); |
| 243 } | 147 } |
| OLD | NEW |