blob: 7f699d1e71269071805d76fe3048e84ad696cd30 [file] [log] [blame]
[email protected]4306df72012-04-20 18:58:571// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]54fd1d32009-09-01 00:12:582// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/memory_details.h"
6
avi6846aef2015-12-26 01:09:387#include <stddef.h>
[email protected]500c8722012-06-18 17:34:238#include <sys/types.h>
9#include <unistd.h>
10
[email protected]e9720e822012-06-07 00:07:4811#include <map>
dcheng4af48582016-04-19 00:29:3512#include <memory>
[email protected]8e2b6472010-12-15 22:19:4813#include <set>
14
[email protected]24d69692011-10-21 18:26:5115#include "base/bind.h"
thestig18dfb7a52014-08-26 10:44:0416#include "base/files/file_util.h"
[email protected]d09a4ce1c2013-07-24 17:37:0217#include "base/process/process_iterator.h"
18#include "base/process/process_metrics.h"
[email protected]48e303442013-07-18 19:13:1519#include "base/strings/string_number_conversions.h"
[email protected]f9b294362013-06-10 20:22:3120#include "base/strings/string_util.h"
[email protected]112158af2013-06-07 23:46:1821#include "base/strings/utf_string_conversions.h"
Etienne Pierre-doray0fbce432018-08-27 20:27:5122#include "base/threading/scoped_blocking_call.h"
avi6846aef2015-12-26 01:09:3823#include "build/build_config.h"
Yuta Hijikata235fc62b2020-12-08 03:48:3224#include "build/chromeos_buildflags.h"
[email protected]54fd1d32009-09-01 00:12:5825#include "chrome/common/chrome_constants.h"
[email protected]af39f002014-08-22 10:18:1826#include "chrome/grit/chromium_strings.h"
Eric Seckler8652dcd52018-09-20 10:42:2827#include "content/public/browser/browser_task_traits.h"
[email protected]c38831a12011-10-28 12:44:4928#include "content/public/browser/browser_thread.h"
[email protected]bd5d6cf2011-12-01 00:39:1229#include "content/public/common/process_type.h"
[email protected]b4320742013-02-06 02:57:3130#include "ui/base/l10n/l10n_util.h"
[email protected]54fd1d32009-09-01 00:12:5831
[email protected]e9720e822012-06-07 00:07:4832using base::ProcessEntry;
asvitkine6f5f3592015-01-21 20:50:3733namespace {
34
[email protected]54fd1d32009-09-01 00:12:5835struct Process {
36 pid_t pid;
37 pid_t parent;
[email protected]54fd1d32009-09-01 00:12:5838};
39
[email protected]e9720e822012-06-07 00:07:4840typedef std::map<pid_t, Process> ProcessMap;
[email protected]54fd1d32009-09-01 00:12:5841
[email protected]e9720e822012-06-07 00:07:4842// Get information on all the processes running on the system.
asvitkine6f5f3592015-01-21 20:50:3743ProcessMap GetProcesses() {
[email protected]e9720e822012-06-07 00:07:4844 ProcessMap map;
[email protected]54fd1d32009-09-01 00:12:5845
[email protected]e9720e822012-06-07 00:07:4846 base::ProcessIterator process_iter(NULL);
47 while (const ProcessEntry* process_entry = process_iter.NextProcessEntry()) {
[email protected]54fd1d32009-09-01 00:12:5848 Process process;
[email protected]e9720e822012-06-07 00:07:4849 process.pid = process_entry->pid();
50 process.parent = process_entry->parent_pid();
[email protected]e9720e822012-06-07 00:07:4851 map.insert(std::make_pair(process.pid, process));
[email protected]54fd1d32009-09-01 00:12:5852 }
[email protected]e9720e822012-06-07 00:07:4853 return map;
[email protected]54fd1d32009-09-01 00:12:5854}
55
[email protected]e9720e822012-06-07 00:07:4856// For each of a list of pids, collect memory information about that process.
asvitkine6f5f3592015-01-21 20:50:3757ProcessData GetProcessDataMemoryInformation(
[email protected]e9720e822012-06-07 00:07:4858 const std::vector<pid_t>& pids) {
59 ProcessData process_data;
asvitkine6f5f3592015-01-21 20:50:3760 for (pid_t pid : pids) {
[email protected]54fd1d32009-09-01 00:12:5861 ProcessMemoryInformation pmi;
62
asvitkine6f5f3592015-01-21 20:50:3763 pmi.pid = pid;
[email protected]54fd1d32009-09-01 00:12:5864 pmi.num_processes = 1;
65
66 if (pmi.pid == base::GetCurrentProcId())
[email protected]f3b357692013-03-22 05:16:1367 pmi.process_type = content::PROCESS_TYPE_BROWSER;
[email protected]54fd1d32009-09-01 00:12:5868 else
[email protected]f3b357692013-03-22 05:16:1369 pmi.process_type = content::PROCESS_TYPE_UNKNOWN;
[email protected]54fd1d32009-09-01 00:12:5870
dcheng4af48582016-04-19 00:29:3571 std::unique_ptr<base::ProcessMetrics> metrics(
asvitkine6f5f3592015-01-21 20:50:3772 base::ProcessMetrics::CreateProcessMetrics(pid));
dcastagnaf454af4e2017-03-15 23:34:1473 pmi.num_open_fds = metrics->GetOpenFdCount();
74 pmi.open_fds_soft_limit = metrics->GetOpenFdSoftLimit();
[email protected]54fd1d32009-09-01 00:12:5875
[email protected]e9720e822012-06-07 00:07:4876 process_data.processes.push_back(pmi);
[email protected]54fd1d32009-09-01 00:12:5877 }
[email protected]e9720e822012-06-07 00:07:4878 return process_data;
[email protected]54fd1d32009-09-01 00:12:5879}
80
[email protected]e9720e822012-06-07 00:07:4881// Find all children of the given process with pid |root|.
asvitkine6f5f3592015-01-21 20:50:3782std::vector<pid_t> GetAllChildren(const ProcessMap& processes, pid_t root) {
[email protected]e9720e822012-06-07 00:07:4883 std::vector<pid_t> children;
84 children.push_back(root);
[email protected]54fd1d32009-09-01 00:12:5885
86 std::set<pid_t> wavefront, next_wavefront;
87 wavefront.insert(root);
88
89 while (wavefront.size()) {
asvitkine6f5f3592015-01-21 20:50:3790 for (const auto& entry : processes) {
91 const Process& process = entry.second;
[email protected]e9720e822012-06-07 00:07:4892 if (wavefront.count(process.parent)) {
93 children.push_back(process.pid);
94 next_wavefront.insert(process.pid);
[email protected]54fd1d32009-09-01 00:12:5895 }
96 }
97
98 wavefront.clear();
99 wavefront.swap(next_wavefront);
100 }
[email protected]e9720e822012-06-07 00:07:48101 return children;
[email protected]54fd1d32009-09-01 00:12:58102}
103
asvitkine6f5f3592015-01-21 20:50:37104} // namespace
105
106MemoryDetails::MemoryDetails() {
107}
108
109ProcessData* MemoryDetails::ChromeBrowser() {
110 return &process_data_[0];
111}
112
[email protected]54fd1d32009-09-01 00:12:58113void MemoryDetails::CollectProcessData(
[email protected]4df3ac62011-03-11 04:38:52114 const std::vector<ProcessMemoryInformation>& child_info) {
Etienne Bergeron436d42212019-02-26 17:15:12115 base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
116 base::BlockingType::MAY_BLOCK);
[email protected]54fd1d32009-09-01 00:12:58117
[email protected]e9720e822012-06-07 00:07:48118 ProcessMap process_map = GetProcesses();
[email protected]54fd1d32009-09-01 00:12:58119 std::set<pid_t> browsers_found;
120
[email protected]e9720e822012-06-07 00:07:48121 ProcessData current_browser =
122 GetProcessDataMemoryInformation(GetAllChildren(process_map, getpid()));
[email protected]b4320742013-02-06 02:57:31123 current_browser.name = l10n_util::GetStringUTF16(IDS_SHORT_PRODUCT_NAME);
Jan Wilken Dörrie78e88d82e2021-03-23 15:24:22124 current_browser.process_name = u"chrome";
[email protected]e1873b92011-05-13 19:22:22125
jdoerrie2f1af512018-10-03 00:59:37126 for (auto i = current_browser.processes.begin();
[email protected]e1873b92011-05-13 19:22:22127 i != current_browser.processes.end(); ++i) {
128 // Check if this is one of the child processes whose data we collected
129 // on the IO thread, and if so copy over that data.
130 for (size_t child = 0; child < child_info.size(); child++) {
131 if (child_info[child].pid != i->pid)
132 continue;
133 i->titles = child_info[child].titles;
[email protected]f3b357692013-03-22 05:16:13134 i->process_type = child_info[child].process_type;
[email protected]e1873b92011-05-13 19:22:22135 break;
136 }
137 }
138
[email protected]54fd1d32009-09-01 00:12:58139 process_data_.push_back(current_browser);
140
Yuta Hijikata235fc62b2020-12-08 03:48:32141#if BUILDFLAG(IS_CHROMEOS_ASH)
[email protected]f4134782013-08-29 21:25:20142 base::GetSwapInfo(&swap_info_);
[email protected]48e303442013-07-18 19:13:15143#endif
144
[email protected]54fd1d32009-09-01 00:12:58145 // Finally return to the browser thread.
Gabriel Charettee7cdc5cd2020-05-27 23:35:05146 content::GetUIThreadTaskRunner({})->PostTask(
147 FROM_HERE,
tzik3f7781d2017-04-20 17:09:33148 base::BindOnce(&MemoryDetails::CollectChildInfoOnUIThread, this));
[email protected]54fd1d32009-09-01 00:12:58149}