blob: bb1341af0778ccbda62fa30ba5c5ee9d7ffe1918 [file] [log] [blame]
Avi Drissman4a8573c2022-09-09 19:35:541// Copyright 2012 The Chromium Authors
[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
Takuto Ikutac8d6b16f2024-04-15 16:59:195#include "chrome/browser/memory_details.h"
6
Erik Chen7970a422018-08-10 18:02:127#include <windows.h>
[email protected]b90d7e802011-01-09 16:32:208
Takuto Ikutac8d6b16f2024-04-15 16:59:199#include <TlHelp32.h>
[email protected]54fd1d32009-09-01 00:12:5810#include <psapi.h>
avi6846aef2015-12-26 01:09:3811#include <stddef.h>
Erik Chen7970a422018-08-10 18:02:1212
dcheng4af48582016-04-19 00:29:3513#include <memory>
14
[email protected]54fd1d32009-09-01 00:12:5815#include "base/file_version_info.h"
[email protected]57999812013-02-24 05:40:5216#include "base/files/file_path.h"
Avi Drissman9269d4ed2023-01-07 01:38:0617#include "base/functional/bind.h"
Lei Zhang46a1cad2022-01-17 10:40:3118#include "base/logging.h"
asvitkine58409e4c2015-01-15 01:25:4519#include "base/path_service.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"
[email protected]b90d7e802011-01-09 16:32:2023#include "base/win/scoped_handle.h"
[email protected]1e67c2b2011-03-04 01:17:3724#include "base/win/windows_version.h"
[email protected]54fd1d32009-09-01 00:12:5825#include "chrome/common/url_constants.h"
Henrique Ferreirod78ab262023-09-13 11:21:4326#include "chrome/grit/branded_strings.h"
sdefresne9fb67692015-08-03 18:48:2227#include "components/version_info/version_info.h"
Eric Seckler8652dcd52018-09-20 10:42:2828#include "content/public/browser/browser_task_traits.h"
[email protected]c38831a12011-10-28 12:44:4929#include "content/public/browser/browser_thread.h"
[email protected]bd5d6cf2011-12-01 00:39:1230#include "content/public/common/process_type.h"
[email protected]c051a1b2011-01-21 23:30:1731#include "ui/base/l10n/l10n_util.h"
[email protected]54fd1d32009-09-01 00:12:5832
asvitkine89406d1f2015-01-17 06:57:1033MemoryDetails::MemoryDetails() {
asvitkine58409e4c2015-01-15 01:25:4534 base::FilePath browser_process_path;
Avi Drissman9098f9002018-05-04 00:11:5235 base::PathService::Get(base::FILE_EXE, &browser_process_path);
asvitkine58409e4c2015-01-15 01:25:4536
ellyjonescd6e449d2016-04-13 19:31:1537 ProcessData process;
38 process.name = l10n_util::GetStringUTF16(IDS_PRODUCT_NAME);
Peter Kasting5105d612021-02-09 22:41:4239 process.process_name = browser_process_path.BaseName().AsUTF16Unsafe();
ellyjonescd6e449d2016-04-13 19:31:1540 process_data_.push_back(process);
[email protected]54fd1d32009-09-01 00:12:5841}
42
43ProcessData* MemoryDetails::ChromeBrowser() {
ellyjonescd6e449d2016-04-13 19:31:1544 return &process_data_[0];
[email protected]54fd1d32009-09-01 00:12:5845}
46
47void MemoryDetails::CollectProcessData(
[email protected]4df3ac62011-03-11 04:38:5248 const std::vector<ProcessMemoryInformation>& child_info) {
Etienne Bergeron436d42212019-02-26 17:15:1249 base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
50 base::BlockingType::MAY_BLOCK);
[email protected]54fd1d32009-09-01 00:12:5851
52 // Clear old data.
ellyjonescd6e449d2016-04-13 19:31:1553 process_data_[0].processes.clear();
[email protected]54fd1d32009-09-01 00:12:5854
[email protected]b90d7e802011-01-09 16:32:2055 base::win::ScopedHandle snapshot(
56 ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0));
[email protected]54fd1d32009-09-01 00:12:5857 PROCESSENTRY32 process_entry = {sizeof(PROCESSENTRY32)};
58 if (!snapshot.Get()) {
jsbell3785ea02016-07-29 16:50:0359 LOG(ERROR) << "CreateToolhelp32Snapshot failed: " << GetLastError();
[email protected]54fd1d32009-09-01 00:12:5860 return;
61 }
rvargasd7743ba2014-09-25 01:35:2862 if (!::Process32First(snapshot.Get(), &process_entry)) {
[email protected]54fd1d32009-09-01 00:12:5863 LOG(ERROR) << "Process32First failed: " << GetLastError();
64 return;
65 }
66 do {
[email protected]a4dc33f2009-10-20 15:09:5567 base::ProcessId pid = process_entry.th32ProcessID;
[email protected]1e67c2b2011-03-04 01:17:3768 base::win::ScopedHandle process_handle(::OpenProcess(
[email protected]54fd1d32009-09-01 00:12:5869 PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid));
Rafael Cintron3ca38fad2025-11-10 17:43:4770 if (!process_handle.is_valid()) {
[email protected]54fd1d32009-09-01 00:12:5871 continue;
Rafael Cintron3ca38fad2025-11-10 17:43:4772 }
Peter Kasting5105d612021-02-09 22:41:4273 if (_wcsicmp(base::as_wcstr(process_data_[0].process_name),
thestig0df2bae82016-07-26 17:59:3674 process_entry.szExeFile) != 0) {
ellyjonescd6e449d2016-04-13 19:31:1575 continue;
thestig0df2bae82016-07-26 17:59:3676 }
77
ellyjonescd6e449d2016-04-13 19:31:1578 // Get Memory Information.
79 ProcessMemoryInformation info;
80 info.pid = pid;
thestig0df2bae82016-07-26 17:59:3681 info.process_type = pid == GetCurrentProcessId()
82 ? content::PROCESS_TYPE_BROWSER
83 : content::PROCESS_TYPE_UNKNOWN;
ellyjonescd6e449d2016-04-13 19:31:1584
ellyjonescd6e449d2016-04-13 19:31:1585 // Get Version Information.
86 info.version = base::ASCIIToUTF16(version_info::GetVersionNumber());
87 // Check if this is one of the child processes whose data we collected
88 // on the IO thread, and if so copy over that data.
thestig0df2bae82016-07-26 17:59:3689 for (const ProcessMemoryInformation& child : child_info) {
90 if (child.pid == info.pid) {
91 info.titles = child.titles;
92 info.process_type = child.process_type;
93 break;
94 }
[email protected]54fd1d32009-09-01 00:12:5895 }
ellyjonescd6e449d2016-04-13 19:31:1596
97 // Add the process info to our list.
98 process_data_[0].processes.push_back(info);
rvargasd7743ba2014-09-25 01:35:2899 } while (::Process32Next(snapshot.Get(), &process_entry));
[email protected]54fd1d32009-09-01 00:12:58100
101 // Finally return to the browser thread.
Gabriel Charettee7cdc5cd2020-05-27 23:35:05102 content::GetUIThreadTaskRunner({})->PostTask(
103 FROM_HERE,
kylechar99ef9042019-02-25 18:09:43104 base::BindOnce(&MemoryDetails::CollectChildInfoOnUIThread, this));
[email protected]54fd1d32009-09-01 00:12:58105}