blob: 94f3621efeb11c4c05b1dfb0090fd8235d97d81e [file] [log] [blame]
Avi Drissman4e1b7bc32022-09-15 14:03:501// Copyright 2021 The Chromium Authors
Sebastien Marchand113505a2021-11-22 20:14:472// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include <memory>
6#include <vector>
7
Sebastien Marchand113505a2021-11-22 20:14:478#include "base/command_line.h"
Avi Drissmanadac21992023-01-11 23:46:399#include "base/functional/bind.h"
10#include "base/functional/callback_forward.h"
11#include "base/functional/callback_helpers.h"
Sebastien Marchanddb5895c02022-02-19 04:49:3112#include "base/memory/ref_counted.h"
Sebastien Marchand113505a2021-11-22 20:14:4713#include "base/path_service.h"
14#include "base/rand_util.h"
Sebastien Marchand113505a2021-11-22 20:14:4715#include "base/task/thread_pool.h"
Sebastien Marchand113505a2021-11-22 20:14:4716#include "build/build_config.h"
17#include "content/public/browser/browser_child_process_host_iterator.h"
18#include "content/public/browser/browser_task_traits.h"
19#include "content/public/browser/browser_thread.h"
Will Harris6f5f50a2021-12-03 17:39:4520#include "content/public/browser/child_process_data.h"
Will Harriscd57b832023-01-05 20:03:1021#include "content/public/browser/child_process_host.h"
Sebastien Marchand113505a2021-11-22 20:14:4722#include "content/public/browser/gpu_utils.h"
23#include "content/public/browser/render_process_host.h"
Sebastien Marchand113505a2021-11-22 20:14:4724#include "content/public/common/content_switches.h"
25#include "content/public/common/profiling_utils.h"
26
Xiaohan Wang1ecfd002022-01-19 22:33:1027#if BUILDFLAG(IS_WIN)
Will Harris6f5f50a2021-12-03 17:39:4528#include "sandbox/policy/mojom/sandbox.mojom-shared.h"
29#endif
30
Sebastien Marchand113505a2021-11-22 20:14:4731namespace content {
32
Sebastien Marchanddb5895c02022-02-19 04:49:3133namespace {
34
35// A refcounted class that runs a closure once it's destroyed.
36class RefCountedScopedClosureRunner
37 : public base::RefCounted<RefCountedScopedClosureRunner> {
Sebastien Marchand113505a2021-11-22 20:14:4738 public:
Sebastien Marchanddb5895c02022-02-19 04:49:3139 RefCountedScopedClosureRunner(base::OnceClosure callback);
Sebastien Marchand113505a2021-11-22 20:14:4740
41 private:
Sebastien Marchanddb5895c02022-02-19 04:49:3142 friend class base::RefCounted<RefCountedScopedClosureRunner>;
43 ~RefCountedScopedClosureRunner() = default;
Sebastien Marchand113505a2021-11-22 20:14:4744
Sebastien Marchanddb5895c02022-02-19 04:49:3145 base::ScopedClosureRunner destruction_callback_;
Sebastien Marchand113505a2021-11-22 20:14:4746};
47
Sebastien Marchanddb5895c02022-02-19 04:49:3148RefCountedScopedClosureRunner::RefCountedScopedClosureRunner(
49 base::OnceClosure callback)
50 : destruction_callback_(std::move(callback)) {}
Sebastien Marchand113505a2021-11-22 20:14:4751
Sebastien Marchanddb5895c02022-02-19 04:49:3152} // namespace
Sebastien Marchand113505a2021-11-22 20:14:4753
Sebastien Marchanddb5895c02022-02-19 04:49:3154void AskAllChildrenToDumpProfilingData(base::OnceClosure callback) {
Sebastien Marchand113505a2021-11-22 20:14:4755 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
56 switches::kSingleProcess)) {
57 return;
58 }
Sebastien Marchanddb5895c02022-02-19 04:49:3159
60 auto closure_runner =
61 base::MakeRefCounted<RefCountedScopedClosureRunner>(std::move(callback));
Sebastien Marchand113505a2021-11-22 20:14:4762
63 // Ask all the renderer processes to dump their profiling data.
64 for (RenderProcessHost::iterator i(RenderProcessHost::AllHostsIterator());
65 !i.IsAtEnd(); i.Advance()) {
66 DCHECK(!i.GetCurrentValue()->GetProcess().is_current());
67 if (!i.GetCurrentValue()->IsInitializedAndNotDead())
68 continue;
69 i.GetCurrentValue()->DumpProfilingData(base::BindOnce(
Sebastien Marchanddb5895c02022-02-19 04:49:3170 [](scoped_refptr<RefCountedScopedClosureRunner>) {}, closure_runner));
Sebastien Marchand113505a2021-11-22 20:14:4771 }
72
73 // Ask all the other child processes to dump their profiling data
74 for (content::BrowserChildProcessHostIterator browser_child_iter;
75 !browser_child_iter.Done(); ++browser_child_iter) {
Xiaohan Wang1ecfd002022-01-19 22:33:1076#if BUILDFLAG(IS_WIN)
Will Harris6f5f50a2021-12-03 17:39:4577 // On Windows, elevated processes are never passed the profiling data file
78 // so cannot dump their data.
Sangbaek Park23cea312024-10-23 21:43:1179 CHECK(browser_child_iter.GetData().sandbox_type.has_value());
Will Harris6f5f50a2021-12-03 17:39:4580 if (browser_child_iter.GetData().sandbox_type ==
81 sandbox::mojom::Sandbox::kNoSandboxAndElevatedPrivileges) {
82 continue;
83 }
84#endif
Sebastien Marchand113505a2021-11-22 20:14:4785 browser_child_iter.GetHost()->DumpProfilingData(base::BindOnce(
Sebastien Marchanddb5895c02022-02-19 04:49:3186 [](scoped_refptr<RefCountedScopedClosureRunner>) {}, closure_runner));
Sebastien Marchand113505a2021-11-22 20:14:4787 }
88
89 if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
90 switches::kInProcessGPU)) {
91 DumpGpuProfilingData(base::BindOnce(
Sebastien Marchanddb5895c02022-02-19 04:49:3192 [](scoped_refptr<RefCountedScopedClosureRunner>) {}, closure_runner));
Sebastien Marchand113505a2021-11-22 20:14:4793 }
Sebastien Marchand113505a2021-11-22 20:14:4794}
95
96} // namespace content