Commit 3d5efafd authored by Mike Wittman's avatar Mike Wittman Committed by Commit Bot

[Sampling profiler] Extract and reuse process type logic

Extracts the logic for determining process type from command line
into a location accessible to all users, and reuses it for all cases
where we determine a process type.

Bug: 1129939
Change-Id: Ie021aaf7275042d7ae271f3eafa315b1efac0df0
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2427129
Commit-Queue: Mike Wittman <wittman@chromium.org>
Reviewed-by: default avatarEtienne Pierre-Doray <etiennep@chromium.org>
Cr-Commit-Position: refs/heads/master@{#812370}
parent fc241402
...@@ -13,6 +13,8 @@ source_set("profiler") { ...@@ -13,6 +13,8 @@ source_set("profiler") {
sources = [ sources = [
"main_thread_stack_sampling_profiler.cc", "main_thread_stack_sampling_profiler.cc",
"process_type.cc",
"process_type.h",
"thread_profiler.cc", "thread_profiler.cc",
"thread_profiler_configuration.cc", "thread_profiler_configuration.cc",
"thread_profiler_platform_configuration.cc", "thread_profiler_platform_configuration.cc",
...@@ -39,4 +41,30 @@ source_set("profiler") { ...@@ -39,4 +41,30 @@ source_set("profiler") {
if (enable_extensions) { if (enable_extensions) {
deps += [ "//extensions/common:common" ] deps += [ "//extensions/common:common" ]
} }
friend = [ ":unit_tests" ]
}
source_set("unit_tests") {
testonly = true
sources = [
"process_type_unittest.cc",
"thread_profiler_platform_configuration_unittest.cc",
"thread_profiler_unittest.cc",
]
deps = [
":profiler",
"//base/test:test_support",
"//chrome/common:non_code_constants",
"//components/metrics",
"//components/version_info:version_info",
"//content/public/common",
"//extensions/buildflags",
]
if (enable_extensions) {
deps += [ "//extensions/common:common" ]
}
} }
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "base/bind.h" #include "base/bind.h"
#include "base/command_line.h" #include "base/command_line.h"
#include "base/threading/platform_thread.h" #include "base/threading/platform_thread.h"
#include "chrome/common/profiler/process_type.h"
#include "chrome/common/profiler/thread_profiler.h" #include "chrome/common/profiler/thread_profiler.h"
#include "components/metrics/call_stack_profile_metrics_provider.h" #include "components/metrics/call_stack_profile_metrics_provider.h"
#include "content/public/common/content_switches.h" #include "content/public/common/content_switches.h"
...@@ -15,12 +16,11 @@ namespace { ...@@ -15,12 +16,11 @@ namespace {
// Returns the profiler appropriate for the current process. // Returns the profiler appropriate for the current process.
std::unique_ptr<ThreadProfiler> CreateThreadProfiler() { std::unique_ptr<ThreadProfiler> CreateThreadProfiler() {
const base::CommandLine* command_line = const metrics::CallStackProfileParams::Process process =
base::CommandLine::ForCurrentProcess(); GetProfileParamsProcess(*base::CommandLine::ForCurrentProcess());
// The browser process has an empty process type.
// TODO(wittman): Do this for other process types too. // TODO(wittman): Do this for other process types too.
if (!command_line->HasSwitch(switches::kProcessType)) { if (process == metrics::CallStackProfileParams::BROWSER_PROCESS) {
ThreadProfiler::SetBrowserProcessReceiverCallback(base::BindRepeating( ThreadProfiler::SetBrowserProcessReceiverCallback(base::BindRepeating(
&metrics::CallStackProfileMetricsProvider::ReceiveProfile)); &metrics::CallStackProfileMetricsProvider::ReceiveProfile));
return ThreadProfiler::CreateAndStartOnMainThread(); return ThreadProfiler::CreateAndStartOnMainThread();
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/common/profiler/process_type.h"
#include "content/public/common/content_switches.h"
#include "extensions/buildflags/buildflags.h"
#include "sandbox/policy/sandbox.h"
#include "services/service_manager/embedder/switches.h"
#if BUILDFLAG(ENABLE_EXTENSIONS)
#include "extensions/common/switches.h"
#endif
namespace {
// True if the command line corresponds to an extension renderer process.
bool IsExtensionRenderer(const base::CommandLine& command_line) {
#if BUILDFLAG(ENABLE_EXTENSIONS)
return command_line.HasSwitch(extensions::switches::kExtensionProcess);
#else
return false;
#endif
}
} // namespace
metrics::CallStackProfileParams::Process GetProfileParamsProcess(
const base::CommandLine& command_line) {
std::string process_type =
command_line.GetSwitchValueASCII(switches::kProcessType);
if (process_type.empty())
return metrics::CallStackProfileParams::BROWSER_PROCESS;
// Renderer process exclusive of extension renderers.
if (process_type == switches::kRendererProcess &&
!IsExtensionRenderer(command_line)) {
return metrics::CallStackProfileParams::RENDERER_PROCESS;
}
if (process_type == switches::kGpuProcess)
return metrics::CallStackProfileParams::GPU_PROCESS;
if (process_type == switches::kUtilityProcess) {
auto sandbox_type =
sandbox::policy::SandboxTypeFromCommandLine(command_line);
if (sandbox_type == sandbox::policy::SandboxType::kNetwork)
return metrics::CallStackProfileParams::NETWORK_SERVICE_PROCESS;
return metrics::CallStackProfileParams::UTILITY_PROCESS;
}
if (process_type == service_manager::switches::kZygoteProcess)
return metrics::CallStackProfileParams::ZYGOTE_PROCESS;
if (process_type == switches::kPpapiPluginProcess)
return metrics::CallStackProfileParams::PPAPI_PLUGIN_PROCESS;
if (process_type == switches::kPpapiBrokerProcess)
return metrics::CallStackProfileParams::PPAPI_BROKER_PROCESS;
return metrics::CallStackProfileParams::UNKNOWN_PROCESS;
}
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_COMMON_PROFILER_PROCESS_TYPE_H_
#define CHROME_COMMON_PROFILER_PROCESS_TYPE_H_
#include "components/metrics/call_stack_profile_params.h"
namespace base {
class CommandLine;
}
metrics::CallStackProfileParams::Process GetProfileParamsProcess(
const base::CommandLine& command_line);
#endif // CHROME_COMMON_PROFILER_PROCESS_TYPE_H_
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/common/profiler/process_type.h"
#include "base/command_line.h"
#include "chrome/common/chrome_switches.h"
#include "content/public/common/content_switches.h"
#include "extensions/buildflags/buildflags.h"
#include "sandbox/policy/switches.h"
#include "testing/gtest/include/gtest/gtest.h"
#if BUILDFLAG(ENABLE_EXTENSIONS)
#include "extensions/common/switches.h"
#endif
class ThreadProfilerProcessTypeTest : public ::testing::Test {
public:
ThreadProfilerProcessTypeTest()
: command_line_(base::CommandLine::NO_PROGRAM) {}
base::CommandLine& command_line() { return command_line_; }
private:
base::CommandLine command_line_;
};
TEST_F(ThreadProfilerProcessTypeTest, GetProfileParamsProcess_Browser) {
// No process type switch == browser process.
EXPECT_EQ(metrics::CallStackProfileParams::BROWSER_PROCESS,
GetProfileParamsProcess(command_line()));
}
TEST_F(ThreadProfilerProcessTypeTest, GetProfileParamsProcess_Renderer) {
command_line().AppendSwitchASCII(switches::kProcessType,
switches::kRendererProcess);
EXPECT_EQ(metrics::CallStackProfileParams::RENDERER_PROCESS,
GetProfileParamsProcess(command_line()));
}
#if BUILDFLAG(ENABLE_EXTENSIONS)
TEST_F(ThreadProfilerProcessTypeTest, GetProfileParamsProcess_Extension) {
command_line().AppendSwitchASCII(switches::kProcessType,
switches::kRendererProcess);
command_line().AppendSwitch(extensions::switches::kExtensionProcess);
// Extension renderers are treated separately from non-extension renderers,
// but don't have a defined enum currently.
EXPECT_EQ(metrics::CallStackProfileParams::UNKNOWN_PROCESS,
GetProfileParamsProcess(command_line()));
}
#endif
TEST_F(ThreadProfilerProcessTypeTest, GetProfileParamsProcess_Gpu) {
command_line().AppendSwitchASCII(switches::kProcessType,
switches::kGpuProcess);
EXPECT_EQ(metrics::CallStackProfileParams::GPU_PROCESS,
GetProfileParamsProcess(command_line()));
}
TEST_F(ThreadProfilerProcessTypeTest, GetProfileParamsProcess_NetworkService) {
command_line().AppendSwitchASCII(switches::kProcessType,
switches::kUtilityProcess);
command_line().AppendSwitchASCII(
sandbox::policy::switches::kServiceSandboxType,
sandbox::policy::switches::kNetworkSandbox);
EXPECT_EQ(metrics::CallStackProfileParams::NETWORK_SERVICE_PROCESS,
GetProfileParamsProcess(command_line()));
}
TEST_F(ThreadProfilerProcessTypeTest, GetProfileParamsProcess_Utility) {
command_line().AppendSwitchASCII(switches::kProcessType,
switches::kUtilityProcess);
EXPECT_EQ(metrics::CallStackProfileParams::UTILITY_PROCESS,
GetProfileParamsProcess(command_line()));
}
TEST_F(ThreadProfilerProcessTypeTest, GetProfileParamsProcess_Zygote) {
command_line().AppendSwitchASCII(switches::kProcessType,
service_manager::switches::kZygoteProcess);
EXPECT_EQ(metrics::CallStackProfileParams::ZYGOTE_PROCESS,
GetProfileParamsProcess(command_line()));
}
TEST_F(ThreadProfilerProcessTypeTest, GetProfileParamsProcess_PpapiPlugin) {
command_line().AppendSwitchASCII(switches::kProcessType,
switches::kPpapiPluginProcess);
EXPECT_EQ(metrics::CallStackProfileParams::PPAPI_PLUGIN_PROCESS,
GetProfileParamsProcess(command_line()));
}
TEST_F(ThreadProfilerProcessTypeTest, GetProfileParamsProcess_PpapiBroker) {
command_line().AppendSwitchASCII(switches::kProcessType,
switches::kPpapiBrokerProcess);
EXPECT_EQ(metrics::CallStackProfileParams::PPAPI_BROKER_PROCESS,
GetProfileParamsProcess(command_line()));
}
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include "base/threading/sequence_local_storage_slot.h" #include "base/threading/sequence_local_storage_slot.h"
#include "base/threading/thread_task_runner_handle.h" #include "base/threading/thread_task_runner_handle.h"
#include "build/build_config.h" #include "build/build_config.h"
#include "chrome/common/profiler/process_type.h"
#include "chrome/common/profiler/thread_profiler_configuration.h" #include "chrome/common/profiler/thread_profiler_configuration.h"
#include "components/metrics/call_stack_profile_builder.h" #include "components/metrics/call_stack_profile_builder.h"
#include "components/metrics/call_stack_profile_metrics_provider.h" #include "components/metrics/call_stack_profile_metrics_provider.h"
...@@ -61,33 +62,6 @@ ThreadProfiler* g_main_thread_instance = nullptr; ...@@ -61,33 +62,6 @@ ThreadProfiler* g_main_thread_instance = nullptr;
// Run continuous profiling 2% of the time. // Run continuous profiling 2% of the time.
constexpr const double kFractionOfExecutionTimeToSample = 0.02; constexpr const double kFractionOfExecutionTimeToSample = 0.02;
CallStackProfileParams::Process GetProcess() {
const base::CommandLine* command_line =
base::CommandLine::ForCurrentProcess();
std::string process_type =
command_line->GetSwitchValueASCII(switches::kProcessType);
if (process_type.empty())
return CallStackProfileParams::BROWSER_PROCESS;
if (process_type == switches::kRendererProcess)
return CallStackProfileParams::RENDERER_PROCESS;
if (process_type == switches::kGpuProcess)
return CallStackProfileParams::GPU_PROCESS;
if (process_type == switches::kUtilityProcess) {
auto sandbox_type =
sandbox::policy::SandboxTypeFromCommandLine(*command_line);
if (sandbox_type == sandbox::policy::SandboxType::kNetwork)
return CallStackProfileParams::NETWORK_SERVICE_PROCESS;
return CallStackProfileParams::UTILITY_PROCESS;
}
if (process_type == service_manager::switches::kZygoteProcess)
return CallStackProfileParams::ZYGOTE_PROCESS;
if (process_type == switches::kPpapiPluginProcess)
return CallStackProfileParams::PPAPI_PLUGIN_PROCESS;
if (process_type == switches::kPpapiBrokerProcess)
return CallStackProfileParams::PPAPI_BROKER_PROCESS;
return CallStackProfileParams::UNKNOWN_PROCESS;
}
bool IsCurrentProcessBackgrounded() { bool IsCurrentProcessBackgrounded() {
#if defined(OS_MAC) #if defined(OS_MAC)
// Port provider that returns the calling process's task port, ignoring its // Port provider that returns the calling process's task port, ignoring its
...@@ -113,7 +87,7 @@ class ChromeUnwinderCreator { ...@@ -113,7 +87,7 @@ class ChromeUnwinderCreator {
base::MemoryMappedFile::Region cfi_region; base::MemoryMappedFile::Region cfi_region;
int fd = base::android::OpenApkAsset(kCfiFileName, &cfi_region); int fd = base::android::OpenApkAsset(kCfiFileName, &cfi_region);
DCHECK(fd >= 0); DCHECK_GE(fd, 0);
bool mapped_file_ok = bool mapped_file_ok =
chrome_cfi_file_.Initialize(base::File(fd), cfi_region); chrome_cfi_file_.Initialize(base::File(fd), cfi_region);
DCHECK(mapped_file_ok); DCHECK(mapped_file_ok);
...@@ -339,7 +313,8 @@ void ThreadProfiler::SetCollectorForChildProcess( ...@@ -339,7 +313,8 @@ void ThreadProfiler::SetCollectorForChildProcess(
if (!ThreadProfilerConfiguration::Get()->IsProfilerEnabledForCurrentProcess()) if (!ThreadProfilerConfiguration::Get()->IsProfilerEnabledForCurrentProcess())
return; return;
DCHECK_NE(CallStackProfileParams::BROWSER_PROCESS, GetProcess()); DCHECK_NE(CallStackProfileParams::BROWSER_PROCESS,
GetProfileParamsProcess(*base::CommandLine::ForCurrentProcess()));
CallStackProfileBuilder::SetParentProfileCollectorForChildProcess( CallStackProfileBuilder::SetParentProfileCollectorForChildProcess(
std::move(collector)); std::move(collector));
} }
...@@ -365,7 +340,8 @@ void ThreadProfiler::SetCollectorForChildProcess( ...@@ -365,7 +340,8 @@ void ThreadProfiler::SetCollectorForChildProcess(
ThreadProfiler::ThreadProfiler( ThreadProfiler::ThreadProfiler(
CallStackProfileParams::Thread thread, CallStackProfileParams::Thread thread,
scoped_refptr<base::SingleThreadTaskRunner> owning_thread_task_runner) scoped_refptr<base::SingleThreadTaskRunner> owning_thread_task_runner)
: process_(GetProcess()), : process_(
GetProfileParamsProcess(*base::CommandLine::ForCurrentProcess())),
thread_(thread), thread_(thread),
owning_thread_task_runner_(owning_thread_task_runner), owning_thread_task_runner_(owning_thread_task_runner),
work_id_recorder_(std::make_unique<WorkIdRecorder>( work_id_recorder_(std::make_unique<WorkIdRecorder>(
......
...@@ -12,9 +12,9 @@ ...@@ -12,9 +12,9 @@
#include "build/branding_buildflags.h" #include "build/branding_buildflags.h"
#include "chrome/common/channel_info.h" #include "chrome/common/channel_info.h"
#include "chrome/common/chrome_switches.h" #include "chrome/common/chrome_switches.h"
#include "chrome/common/profiler/process_type.h"
#include "chrome/common/profiler/thread_profiler_platform_configuration.h" #include "chrome/common/profiler/thread_profiler_platform_configuration.h"
#include "components/version_info/version_info.h" #include "components/version_info/version_info.h"
#include "content/public/common/content_switches.h"
namespace { namespace {
...@@ -22,14 +22,6 @@ base::LazyInstance<ThreadProfilerConfiguration>::Leaky g_configuration = ...@@ -22,14 +22,6 @@ base::LazyInstance<ThreadProfilerConfiguration>::Leaky g_configuration =
LAZY_INSTANCE_INITIALIZER; LAZY_INSTANCE_INITIALIZER;
// Returns true if the current execution is taking place in the browser process. // Returns true if the current execution is taking place in the browser process.
bool IsBrowserProcess() {
const base::CommandLine* command_line =
base::CommandLine::ForCurrentProcess();
std::string process_type =
command_line->GetSwitchValueASCII(switches::kProcessType);
return process_type.empty();
}
// Allows the profiler to be run in a special browser test mode for testing that // Allows the profiler to be run in a special browser test mode for testing that
// profiles are collected as expected, by providing a switch value. The test // profiles are collected as expected, by providing a switch value. The test
// mode reduces the profiling duration to ensure the startup profiles complete // mode reduces the profiling duration to ensure the startup profiles complete
...@@ -44,9 +36,12 @@ bool IsBrowserTestModeEnabled() { ...@@ -44,9 +36,12 @@ bool IsBrowserTestModeEnabled() {
} // namespace } // namespace
ThreadProfilerConfiguration::ThreadProfilerConfiguration() ThreadProfilerConfiguration::ThreadProfilerConfiguration()
: platform_configuration_(ThreadProfilerPlatformConfiguration::Create( : current_process_(
GetProfileParamsProcess(*base::CommandLine::ForCurrentProcess())),
platform_configuration_(ThreadProfilerPlatformConfiguration::Create(
IsBrowserTestModeEnabled())), IsBrowserTestModeEnabled())),
configuration_(GenerateConfiguration(*platform_configuration_)) {} configuration_(
GenerateConfiguration(current_process_, *platform_configuration_)) {}
ThreadProfilerConfiguration::~ThreadProfilerConfiguration() = default; ThreadProfilerConfiguration::~ThreadProfilerConfiguration() = default;
...@@ -66,7 +61,7 @@ ThreadProfilerConfiguration::GetSamplingParams() const { ...@@ -66,7 +61,7 @@ ThreadProfilerConfiguration::GetSamplingParams() const {
} }
bool ThreadProfilerConfiguration::IsProfilerEnabledForCurrentProcess() const { bool ThreadProfilerConfiguration::IsProfilerEnabledForCurrentProcess() const {
if (IsBrowserProcess()) { if (current_process_ == metrics::CallStackProfileParams::BROWSER_PROCESS) {
return configuration_ == PROFILE_ENABLED || return configuration_ == PROFILE_ENABLED ||
configuration_ == PROFILE_CONTROL; configuration_ == PROFILE_CONTROL;
} }
...@@ -74,15 +69,14 @@ bool ThreadProfilerConfiguration::IsProfilerEnabledForCurrentProcess() const { ...@@ -74,15 +69,14 @@ bool ThreadProfilerConfiguration::IsProfilerEnabledForCurrentProcess() const {
DCHECK_EQ(PROFILE_FROM_COMMAND_LINE, configuration_); DCHECK_EQ(PROFILE_FROM_COMMAND_LINE, configuration_);
// This is a child process. The |kStartStackProfiler| switch passed by the // This is a child process. The |kStartStackProfiler| switch passed by the
// browser process determines whether the profiler is enabled for the process. // browser process determines whether the profiler is enabled for the process.
const base::CommandLine* command_line = return base::CommandLine::ForCurrentProcess()->HasSwitch(
base::CommandLine::ForCurrentProcess(); switches::kStartStackProfiler);
return command_line->HasSwitch(switches::kStartStackProfiler);
} }
bool ThreadProfilerConfiguration::GetSyntheticFieldTrial( bool ThreadProfilerConfiguration::GetSyntheticFieldTrial(
std::string* trial_name, std::string* trial_name,
std::string* group_name) const { std::string* group_name) const {
DCHECK(IsBrowserProcess()); DCHECK_EQ(metrics::CallStackProfileParams::BROWSER_PROCESS, current_process_);
if (!platform_configuration_->IsSupported(BUILDFLAG(GOOGLE_CHROME_BRANDING), if (!platform_configuration_->IsSupported(BUILDFLAG(GOOGLE_CHROME_BRANDING),
chrome::GetChannel())) { chrome::GetChannel())) {
...@@ -117,23 +111,26 @@ bool ThreadProfilerConfiguration::GetSyntheticFieldTrial( ...@@ -117,23 +111,26 @@ bool ThreadProfilerConfiguration::GetSyntheticFieldTrial(
} }
void ThreadProfilerConfiguration::AppendCommandLineSwitchForChildProcess( void ThreadProfilerConfiguration::AppendCommandLineSwitchForChildProcess(
base::CommandLine* command_line) const { base::CommandLine* child_process_command_line) const {
DCHECK(IsBrowserProcess()); DCHECK_EQ(metrics::CallStackProfileParams::BROWSER_PROCESS, current_process_);
if (!(configuration_ == PROFILE_ENABLED || configuration_ == PROFILE_CONTROL)) if (!(configuration_ == PROFILE_ENABLED || configuration_ == PROFILE_CONTROL))
return; return;
const metrics::CallStackProfileParams::Process child_process =
GetProfileParamsProcess(*child_process_command_line);
const double enable_fraction = const double enable_fraction =
platform_configuration_->GetChildProcessEnableFraction(*command_line); platform_configuration_->GetChildProcessEnableFraction(child_process);
if (!(base::RandDouble() < enable_fraction)) if (!(base::RandDouble() < enable_fraction))
return; return;
if (IsBrowserTestModeEnabled()) { if (IsBrowserTestModeEnabled()) {
// Propagate the browser test mode switch argument to the child processes. // Propagate the browser test mode switch argument to the child processes.
command_line->AppendSwitchASCII(switches::kStartStackProfiler, child_process_command_line->AppendSwitchASCII(
switches::kStartStackProfilerBrowserTest); switches::kStartStackProfiler,
switches::kStartStackProfilerBrowserTest);
} else { } else {
command_line->AppendSwitch(switches::kStartStackProfiler); child_process_command_line->AppendSwitch(switches::kStartStackProfiler);
} }
} }
...@@ -167,8 +164,9 @@ ThreadProfilerConfiguration::ChooseConfiguration( ...@@ -167,8 +164,9 @@ ThreadProfilerConfiguration::ChooseConfiguration(
// static // static
ThreadProfilerConfiguration::ProfileConfiguration ThreadProfilerConfiguration::ProfileConfiguration
ThreadProfilerConfiguration::GenerateConfiguration( ThreadProfilerConfiguration::GenerateConfiguration(
metrics::CallStackProfileParams::Process process,
const ThreadProfilerPlatformConfiguration& platform_configuration) { const ThreadProfilerPlatformConfiguration& platform_configuration) {
if (!IsBrowserProcess()) if (process != metrics::CallStackProfileParams::BROWSER_PROCESS)
return PROFILE_FROM_COMMAND_LINE; return PROFILE_FROM_COMMAND_LINE;
const version_info::Channel channel = chrome::GetChannel(); const version_info::Channel channel = chrome::GetChannel();
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "base/callback.h" #include "base/callback.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/profiler/stack_sampling_profiler.h" #include "base/profiler/stack_sampling_profiler.h"
#include "components/metrics/call_stack_profile_params.h"
namespace base { namespace base {
class CommandLine; class CommandLine;
...@@ -75,11 +76,16 @@ class ThreadProfilerConfiguration { ...@@ -75,11 +76,16 @@ class ThreadProfilerConfiguration {
// Generates sampling profiler configurations for all processes. // Generates sampling profiler configurations for all processes.
static ProfileConfiguration GenerateConfiguration( static ProfileConfiguration GenerateConfiguration(
metrics::CallStackProfileParams::Process process,
const ThreadProfilerPlatformConfiguration& platform_configuration); const ThreadProfilerPlatformConfiguration& platform_configuration);
// NOTE: all state in this class must be const and initialized at construction // NOTE: all state in this class must be const and initialized at construction
// time to ensure thread-safe access post-construction. // time to ensure thread-safe access post-construction.
// The currently-executing process.
const metrics::CallStackProfileParams::Process current_process_;
// Platform-dependent configuration upon which |configuration_| is based.
const std::unique_ptr<ThreadProfilerPlatformConfiguration> const std::unique_ptr<ThreadProfilerPlatformConfiguration>
platform_configuration_; platform_configuration_;
......
...@@ -7,18 +7,12 @@ ...@@ -7,18 +7,12 @@
#include "base/command_line.h" #include "base/command_line.h"
#include "base/profiler/stack_sampling_profiler.h" #include "base/profiler/stack_sampling_profiler.h"
#include "build/build_config.h" #include "build/build_config.h"
#include "content/public/common/content_switches.h" #include "chrome/common/profiler/process_type.h"
#include "extensions/buildflags/buildflags.h"
#include "sandbox/policy/sandbox.h"
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
#include "chrome/android/modules/stack_unwinder/public/module.h" #include "chrome/android/modules/stack_unwinder/public/module.h"
#endif #endif
#if BUILDFLAG(ENABLE_EXTENSIONS)
#include "extensions/common/switches.h"
#endif
namespace { namespace {
// The default configuration to use in the absence of special circumstances on a // The default configuration to use in the absence of special circumstances on a
...@@ -38,15 +32,12 @@ class DefaultPlatformConfiguration ...@@ -38,15 +32,12 @@ class DefaultPlatformConfiguration
version_info::Channel channel) const override; version_info::Channel channel) const override;
double GetChildProcessEnableFraction( double GetChildProcessEnableFraction(
const base::CommandLine& child_process_command_line) const override; metrics::CallStackProfileParams::Process process) const override;
protected: protected:
bool IsSupportedForChannel(bool is_chrome_branded, bool IsSupportedForChannel(bool is_chrome_branded,
version_info::Channel channel) const override; version_info::Channel channel) const override;
// True if the command line corresponds to an extension renderer process.
bool IsExtensionRenderer(const base::CommandLine& command_line) const;
bool browser_test_mode_enabled() const { return browser_test_mode_enabled_; } bool browser_test_mode_enabled() const { return browser_test_mode_enabled_; }
private: private:
...@@ -85,30 +76,25 @@ DefaultPlatformConfiguration::GetEnableRates( ...@@ -85,30 +76,25 @@ DefaultPlatformConfiguration::GetEnableRates(
} }
double DefaultPlatformConfiguration::GetChildProcessEnableFraction( double DefaultPlatformConfiguration::GetChildProcessEnableFraction(
const base::CommandLine& child_process_command_line) const { metrics::CallStackProfileParams::Process process) const {
const std::string& process_type = DCHECK_NE(metrics::CallStackProfileParams::BROWSER_PROCESS, process);
child_process_command_line.GetSwitchValueASCII(switches::kProcessType);
switch (process) {
if (process_type == switches::kGpuProcess) case metrics::CallStackProfileParams::GPU_PROCESS:
return 1.0; case metrics::CallStackProfileParams::NETWORK_SERVICE_PROCESS:
return 1.0;
// The network service is the only utility process that is profiled for now. break;
if (process_type == switches::kUtilityProcess &&
sandbox::policy::SandboxTypeFromCommandLine(child_process_command_line) == case metrics::CallStackProfileParams::RENDERER_PROCESS:
sandbox::policy::SandboxType::kNetwork) { // Run the profiler in all renderer processes if the browser test mode is
return 1.0; // enabled, otherwise run in 20% of the processes to collect roughly as
} // many profiles for renderer processes as browser processes.
return browser_test_mode_enabled() ? 1.0 : 0.2;
break;
// Only start the profiler for non-extension renderer processes. default:
if (process_type == switches::kRendererProcess && return 0.0;
!IsExtensionRenderer(child_process_command_line)) {
// Run the profiler in all renderer processes if the browser test mode is
// enabled, otherwise run in 20% of the processes to collect roughly as
// many profiles for renderer processes as browser processes.
return browser_test_mode_enabled() ? 1.0 : 0.2;
} }
return 0.0;
} }
bool DefaultPlatformConfiguration::IsSupportedForChannel( bool DefaultPlatformConfiguration::IsSupportedForChannel(
...@@ -124,23 +110,7 @@ bool DefaultPlatformConfiguration::IsSupportedForChannel( ...@@ -124,23 +110,7 @@ bool DefaultPlatformConfiguration::IsSupportedForChannel(
channel == version_info::Channel::DEV; channel == version_info::Channel::DEV;
} }
// True if the command line corresponds to an extension renderer process.
bool DefaultPlatformConfiguration::IsExtensionRenderer(
const base::CommandLine& command_line) const {
#if BUILDFLAG(ENABLE_EXTENSIONS)
return command_line.HasSwitch(extensions::switches::kExtensionProcess);
#else
return false;
#endif
}
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
bool IsBrowserProcess() {
return base::CommandLine::ForCurrentProcess()
->GetSwitchValueASCII(switches::kProcessType)
.empty();
}
// The configuration to use for the Android platform. Applies to ARM32 which is // The configuration to use for the Android platform. Applies to ARM32 which is
// the only Android architecture currently supported by StackSamplingProfiler. // the only Android architecture currently supported by StackSamplingProfiler.
// Defined in terms of DefaultPlatformConfiguration where Android does not // Defined in terms of DefaultPlatformConfiguration where Android does not
...@@ -157,7 +127,7 @@ class AndroidPlatformConfiguration : public DefaultPlatformConfiguration { ...@@ -157,7 +127,7 @@ class AndroidPlatformConfiguration : public DefaultPlatformConfiguration {
void RequestRuntimeModuleInstall() const override; void RequestRuntimeModuleInstall() const override;
double GetChildProcessEnableFraction( double GetChildProcessEnableFraction(
const base::CommandLine& child_process_command_line) const override; metrics::CallStackProfileParams::Process process) const override;
protected: protected:
bool IsSupportedForChannel(bool is_chrome_branded, bool IsSupportedForChannel(bool is_chrome_branded,
...@@ -201,7 +171,8 @@ AndroidPlatformConfiguration::GetRuntimeModuleState( ...@@ -201,7 +171,8 @@ AndroidPlatformConfiguration::GetRuntimeModuleState(
void AndroidPlatformConfiguration::RequestRuntimeModuleInstall() const { void AndroidPlatformConfiguration::RequestRuntimeModuleInstall() const {
// The install can only be done in the browser process. // The install can only be done in the browser process.
CHECK(IsBrowserProcess()); CHECK_EQ(metrics::CallStackProfileParams::BROWSER_PROCESS,
GetProfileParamsProcess(*base::CommandLine::ForCurrentProcess()));
// The install occurs asynchronously, with the module available at the first // The install occurs asynchronously, with the module available at the first
// run of Chrome following install. // run of Chrome following install.
...@@ -209,13 +180,11 @@ void AndroidPlatformConfiguration::RequestRuntimeModuleInstall() const { ...@@ -209,13 +180,11 @@ void AndroidPlatformConfiguration::RequestRuntimeModuleInstall() const {
} }
double AndroidPlatformConfiguration::GetChildProcessEnableFraction( double AndroidPlatformConfiguration::GetChildProcessEnableFraction(
const base::CommandLine& child_process_command_line) const { metrics::CallStackProfileParams::Process process) const {
// Profile all processes in browser test mode since they're disabled // Profile all processes in browser test mode since they're disabled
// otherwise. // otherwise.
if (browser_test_mode_enabled()) { if (browser_test_mode_enabled())
return DefaultPlatformConfiguration::GetChildProcessEnableFraction( return DefaultPlatformConfiguration::GetChildProcessEnableFraction(process);
child_process_command_line);
}
// TODO(https://crbug.com/1004855): Enable for all the default processes. // TODO(https://crbug.com/1004855): Enable for all the default processes.
return 0.0; return 0.0;
......
...@@ -7,12 +7,9 @@ ...@@ -7,12 +7,9 @@
#include <memory> #include <memory>
#include "components/metrics/call_stack_profile_params.h"
#include "components/version_info/version_info.h" #include "components/version_info/version_info.h"
namespace base {
class CommandLine;
}
// Encapsulates the platform-specific configuration for the ThreadProfiler. // Encapsulates the platform-specific configuration for the ThreadProfiler.
// //
// The interface functions this class make a distinction between 'supported' and // The interface functions this class make a distinction between 'supported' and
...@@ -80,10 +77,9 @@ class ThreadProfilerPlatformConfiguration { ...@@ -80,10 +77,9 @@ class ThreadProfilerPlatformConfiguration {
version_info::Channel channel) const = 0; version_info::Channel channel) const = 0;
// Returns the fraction of the time that profiling should be randomly enabled // Returns the fraction of the time that profiling should be randomly enabled
// for the child process to be executed with |child_process_command_line|. The // for the child |process|. The return value is in the range [0.0, 1.0].
// return value is in the range [0.0, 1.0].
virtual double GetChildProcessEnableFraction( virtual double GetChildProcessEnableFraction(
const base::CommandLine& child_process_command_line) const = 0; metrics::CallStackProfileParams::Process process) const = 0;
protected: protected:
// True if the profiler is to be run for the channel/chrome branding on the // True if the profiler is to be run for the channel/chrome branding on the
......
...@@ -6,20 +6,11 @@ ...@@ -6,20 +6,11 @@
#include <utility> #include <utility>
#include "base/command_line.h"
#include "base/profiler/profiler_buildflags.h" #include "base/profiler/profiler_buildflags.h"
#include "build/build_config.h" #include "build/build_config.h"
#include "chrome/common/chrome_switches.h"
#include "components/version_info/version_info.h" #include "components/version_info/version_info.h"
#include "content/public/common/content_switches.h"
#include "extensions/buildflags/buildflags.h"
#include "sandbox/policy/switches.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
#if BUILDFLAG(ENABLE_EXTENSIONS)
#include "extensions/common/switches.h"
#endif
#if (defined(OS_WIN) && defined(ARCH_CPU_X86_64)) || \ #if (defined(OS_WIN) && defined(ARCH_CPU_X86_64)) || \
(defined(OS_MAC) && defined(ARCH_CPU_X86_64)) || \ (defined(OS_MAC) && defined(ARCH_CPU_X86_64)) || \
(defined(OS_ANDROID) && BUILDFLAG(ENABLE_ARM_CFI_TABLE)) (defined(OS_ANDROID) && BUILDFLAG(ENABLE_ARM_CFI_TABLE))
...@@ -52,30 +43,6 @@ class ThreadProfilerPlatformConfigurationTest : public ::testing::Test { ...@@ -52,30 +43,6 @@ class ThreadProfilerPlatformConfigurationTest : public ::testing::Test {
const std::unique_ptr<ThreadProfilerPlatformConfiguration> config_; const std::unique_ptr<ThreadProfilerPlatformConfiguration> config_;
}; };
// Utility type and function for testing various command line switches.
struct Switch {
explicit Switch(const char* name, const char* value = nullptr)
: name(name), value(value) {}
const char* name;
const char* value;
};
// Second argument should be a lambda running the expectations for the given
// switch configuration.
template <typename Func>
void WithSwitches(std::initializer_list<Switch> switches, const Func& func) {
base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
for (const auto& switch_pair : switches) {
if (!switch_pair.value)
command_line.AppendSwitch(switch_pair.name);
else
command_line.AppendSwitchASCII(switch_pair.name, switch_pair.value);
}
func(command_line);
}
} // namespace } // namespace
// Glue functions to make RelativePopulations work with googletest. // Glue functions to make RelativePopulations work with googletest.
...@@ -214,64 +181,26 @@ MAYBE_PLATFORM_CONFIG_TEST_F(ThreadProfilerPlatformConfigurationTest, ...@@ -214,64 +181,26 @@ MAYBE_PLATFORM_CONFIG_TEST_F(ThreadProfilerPlatformConfigurationTest,
MAYBE_PLATFORM_CONFIG_TEST_F(ThreadProfilerPlatformConfigurationTest, MAYBE_PLATFORM_CONFIG_TEST_F(ThreadProfilerPlatformConfigurationTest,
GetChildProcessEnableFraction) { GetChildProcessEnableFraction) {
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
WithSwitches( EXPECT_EQ(0.0, config()->GetChildProcessEnableFraction(
{Switch(switches::kProcessType, switches::kGpuProcess)}, metrics::CallStackProfileParams::GPU_PROCESS));
[this](const base::CommandLine command_line) { EXPECT_EQ(0.0, config()->GetChildProcessEnableFraction(
EXPECT_EQ(0.0, config()->GetChildProcessEnableFraction(command_line)); metrics::CallStackProfileParams::RENDERER_PROCESS));
}); EXPECT_EQ(0.0, config()->GetChildProcessEnableFraction(
WithSwitches( metrics::CallStackProfileParams::NETWORK_SERVICE_PROCESS));
{Switch(switches::kProcessType, switches::kUtilityProcess), EXPECT_EQ(0.0, config()->GetChildProcessEnableFraction(
Switch(sandbox::policy::switches::kServiceSandboxType, metrics::CallStackProfileParams::UTILITY_PROCESS));
sandbox::policy::switches::kNetworkSandbox)}, EXPECT_EQ(0.0, config()->GetChildProcessEnableFraction(
[this](const base::CommandLine command_line) { metrics::CallStackProfileParams::UNKNOWN_PROCESS));
EXPECT_EQ(0.0, config()->GetChildProcessEnableFraction(command_line));
});
WithSwitches(
{Switch(switches::kProcessType, switches::kUtilityProcess)},
[this](const base::CommandLine command_line) {
EXPECT_EQ(0.0, config()->GetChildProcessEnableFraction(command_line));
});
WithSwitches(
{Switch(switches::kProcessType, switches::kRendererProcess)},
[this](const base::CommandLine command_line) {
EXPECT_EQ(0.0, config()->GetChildProcessEnableFraction(command_line));
});
// Should be an unrecognized scenario.
WithSwitches({}, [this](const base::CommandLine command_line) {
EXPECT_EQ(0.0, config()->GetChildProcessEnableFraction(command_line));
});
#else #else
WithSwitches( EXPECT_EQ(1.0, config()->GetChildProcessEnableFraction(
{Switch(switches::kProcessType, switches::kGpuProcess)}, metrics::CallStackProfileParams::GPU_PROCESS));
[this](const base::CommandLine command_line) { EXPECT_EQ(0.2, config()->GetChildProcessEnableFraction(
EXPECT_EQ(1.0, config()->GetChildProcessEnableFraction(command_line)); metrics::CallStackProfileParams::RENDERER_PROCESS));
}); EXPECT_EQ(1.0, config()->GetChildProcessEnableFraction(
WithSwitches( metrics::CallStackProfileParams::NETWORK_SERVICE_PROCESS));
{Switch(switches::kProcessType, switches::kUtilityProcess), EXPECT_EQ(0.0, config()->GetChildProcessEnableFraction(
Switch(sandbox::policy::switches::kServiceSandboxType, metrics::CallStackProfileParams::UTILITY_PROCESS));
sandbox::policy::switches::kNetworkSandbox)}, EXPECT_EQ(0.0, config()->GetChildProcessEnableFraction(
[this](const base::CommandLine command_line) { metrics::CallStackProfileParams::UNKNOWN_PROCESS));
EXPECT_EQ(1.0, config()->GetChildProcessEnableFraction(command_line));
});
WithSwitches(
{Switch(switches::kProcessType, switches::kUtilityProcess)},
[this](const base::CommandLine command_line) {
EXPECT_EQ(0.0, config()->GetChildProcessEnableFraction(command_line));
});
WithSwitches(
{Switch(switches::kProcessType, switches::kRendererProcess),
Switch(extensions::switches::kExtensionProcess)},
[this](const base::CommandLine command_line) {
EXPECT_EQ(0.0, config()->GetChildProcessEnableFraction(command_line));
});
WithSwitches(
{Switch(switches::kProcessType, switches::kRendererProcess)},
[this](const base::CommandLine command_line) {
EXPECT_EQ(0.2, config()->GetChildProcessEnableFraction(command_line));
});
// Should be an unrecognized scenario.
WithSwitches({}, [this](const base::CommandLine command_line) {
EXPECT_EQ(0.0, config()->GetChildProcessEnableFraction(command_line));
});
#endif #endif
} }
...@@ -3777,8 +3777,6 @@ test("unit_tests") { ...@@ -3777,8 +3777,6 @@ test("unit_tests") {
"../common/mac/mock_launchd.mm", "../common/mac/mock_launchd.mm",
"../common/net/safe_search_util_unittest.cc", "../common/net/safe_search_util_unittest.cc",
"../common/pref_names_util_unittest.cc", "../common/pref_names_util_unittest.cc",
"../common/profiler/thread_profiler_platform_configuration_unittest.cc",
"../common/profiler/thread_profiler_unittest.cc",
"../common/qr_code_generator/qr_code_generator_unittest.cc", "../common/qr_code_generator/qr_code_generator_unittest.cc",
"../renderer/chrome_content_renderer_client_unittest.cc", "../renderer/chrome_content_renderer_client_unittest.cc",
"../renderer/chrome_render_frame_observer_unittest.cc", "../renderer/chrome_render_frame_observer_unittest.cc",
...@@ -4006,6 +4004,7 @@ test("unit_tests") { ...@@ -4006,6 +4004,7 @@ test("unit_tests") {
"//chrome/browser/video_tutorials:unit_tests", "//chrome/browser/video_tutorials:unit_tests",
"//chrome/common:test_support", "//chrome/common:test_support",
"//chrome/common/privacy_budget:unit_tests", "//chrome/common/privacy_budget:unit_tests",
"//chrome/common/profiler:unit_tests",
"//chrome/services/machine_learning:unit_tests", "//chrome/services/machine_learning:unit_tests",
"//chrome/services/machine_learning/public/cpp:test_support", "//chrome/services/machine_learning/public/cpp:test_support",
"//components/account_id", "//components/account_id",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment