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") {
sources = [
"main_thread_stack_sampling_profiler.cc",
"process_type.cc",
"process_type.h",
"thread_profiler.cc",
"thread_profiler_configuration.cc",
"thread_profiler_platform_configuration.cc",
......@@ -39,4 +41,30 @@ source_set("profiler") {
if (enable_extensions) {
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 @@
#include "base/bind.h"
#include "base/command_line.h"
#include "base/threading/platform_thread.h"
#include "chrome/common/profiler/process_type.h"
#include "chrome/common/profiler/thread_profiler.h"
#include "components/metrics/call_stack_profile_metrics_provider.h"
#include "content/public/common/content_switches.h"
......@@ -15,12 +16,11 @@ namespace {
// Returns the profiler appropriate for the current process.
std::unique_ptr<ThreadProfiler> CreateThreadProfiler() {
const base::CommandLine* command_line =
base::CommandLine::ForCurrentProcess();
const metrics::CallStackProfileParams::Process process =
GetProfileParamsProcess(*base::CommandLine::ForCurrentProcess());
// The browser process has an empty process type.
// 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(
&metrics::CallStackProfileMetricsProvider::ReceiveProfile));
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 @@
#include "base/threading/sequence_local_storage_slot.h"
#include "base/threading/thread_task_runner_handle.h"
#include "build/build_config.h"
#include "chrome/common/profiler/process_type.h"
#include "chrome/common/profiler/thread_profiler_configuration.h"
#include "components/metrics/call_stack_profile_builder.h"
#include "components/metrics/call_stack_profile_metrics_provider.h"
......@@ -61,33 +62,6 @@ ThreadProfiler* g_main_thread_instance = nullptr;
// Run continuous profiling 2% of the time.
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() {
#if defined(OS_MAC)
// Port provider that returns the calling process's task port, ignoring its
......@@ -113,7 +87,7 @@ class ChromeUnwinderCreator {
base::MemoryMappedFile::Region cfi_region;
int fd = base::android::OpenApkAsset(kCfiFileName, &cfi_region);
DCHECK(fd >= 0);
DCHECK_GE(fd, 0);
bool mapped_file_ok =
chrome_cfi_file_.Initialize(base::File(fd), cfi_region);
DCHECK(mapped_file_ok);
......@@ -339,7 +313,8 @@ void ThreadProfiler::SetCollectorForChildProcess(
if (!ThreadProfilerConfiguration::Get()->IsProfilerEnabledForCurrentProcess())
return;
DCHECK_NE(CallStackProfileParams::BROWSER_PROCESS, GetProcess());
DCHECK_NE(CallStackProfileParams::BROWSER_PROCESS,
GetProfileParamsProcess(*base::CommandLine::ForCurrentProcess()));
CallStackProfileBuilder::SetParentProfileCollectorForChildProcess(
std::move(collector));
}
......@@ -365,7 +340,8 @@ void ThreadProfiler::SetCollectorForChildProcess(
ThreadProfiler::ThreadProfiler(
CallStackProfileParams::Thread thread,
scoped_refptr<base::SingleThreadTaskRunner> owning_thread_task_runner)
: process_(GetProcess()),
: process_(
GetProfileParamsProcess(*base::CommandLine::ForCurrentProcess())),
thread_(thread),
owning_thread_task_runner_(owning_thread_task_runner),
work_id_recorder_(std::make_unique<WorkIdRecorder>(
......
......@@ -12,9 +12,9 @@
#include "build/branding_buildflags.h"
#include "chrome/common/channel_info.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/profiler/process_type.h"
#include "chrome/common/profiler/thread_profiler_platform_configuration.h"
#include "components/version_info/version_info.h"
#include "content/public/common/content_switches.h"
namespace {
......@@ -22,14 +22,6 @@ base::LazyInstance<ThreadProfilerConfiguration>::Leaky g_configuration =
LAZY_INSTANCE_INITIALIZER;
// 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
// profiles are collected as expected, by providing a switch value. The test
// mode reduces the profiling duration to ensure the startup profiles complete
......@@ -44,9 +36,12 @@ bool IsBrowserTestModeEnabled() {
} // namespace
ThreadProfilerConfiguration::ThreadProfilerConfiguration()
: platform_configuration_(ThreadProfilerPlatformConfiguration::Create(
: current_process_(
GetProfileParamsProcess(*base::CommandLine::ForCurrentProcess())),
platform_configuration_(ThreadProfilerPlatformConfiguration::Create(
IsBrowserTestModeEnabled())),
configuration_(GenerateConfiguration(*platform_configuration_)) {}
configuration_(
GenerateConfiguration(current_process_, *platform_configuration_)) {}
ThreadProfilerConfiguration::~ThreadProfilerConfiguration() = default;
......@@ -66,7 +61,7 @@ ThreadProfilerConfiguration::GetSamplingParams() const {
}
bool ThreadProfilerConfiguration::IsProfilerEnabledForCurrentProcess() const {
if (IsBrowserProcess()) {
if (current_process_ == metrics::CallStackProfileParams::BROWSER_PROCESS) {
return configuration_ == PROFILE_ENABLED ||
configuration_ == PROFILE_CONTROL;
}
......@@ -74,15 +69,14 @@ bool ThreadProfilerConfiguration::IsProfilerEnabledForCurrentProcess() const {
DCHECK_EQ(PROFILE_FROM_COMMAND_LINE, configuration_);
// This is a child process. The |kStartStackProfiler| switch passed by the
// browser process determines whether the profiler is enabled for the process.
const base::CommandLine* command_line =
base::CommandLine::ForCurrentProcess();
return command_line->HasSwitch(switches::kStartStackProfiler);
return base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kStartStackProfiler);
}
bool ThreadProfilerConfiguration::GetSyntheticFieldTrial(
std::string* trial_name,
std::string* group_name) const {
DCHECK(IsBrowserProcess());
DCHECK_EQ(metrics::CallStackProfileParams::BROWSER_PROCESS, current_process_);
if (!platform_configuration_->IsSupported(BUILDFLAG(GOOGLE_CHROME_BRANDING),
chrome::GetChannel())) {
......@@ -117,23 +111,26 @@ bool ThreadProfilerConfiguration::GetSyntheticFieldTrial(
}
void ThreadProfilerConfiguration::AppendCommandLineSwitchForChildProcess(
base::CommandLine* command_line) const {
DCHECK(IsBrowserProcess());
base::CommandLine* child_process_command_line) const {
DCHECK_EQ(metrics::CallStackProfileParams::BROWSER_PROCESS, current_process_);
if (!(configuration_ == PROFILE_ENABLED || configuration_ == PROFILE_CONTROL))
return;
const metrics::CallStackProfileParams::Process child_process =
GetProfileParamsProcess(*child_process_command_line);
const double enable_fraction =
platform_configuration_->GetChildProcessEnableFraction(*command_line);
platform_configuration_->GetChildProcessEnableFraction(child_process);
if (!(base::RandDouble() < enable_fraction))
return;
if (IsBrowserTestModeEnabled()) {
// Propagate the browser test mode switch argument to the child processes.
command_line->AppendSwitchASCII(switches::kStartStackProfiler,
child_process_command_line->AppendSwitchASCII(
switches::kStartStackProfiler,
switches::kStartStackProfilerBrowserTest);
} else {
command_line->AppendSwitch(switches::kStartStackProfiler);
child_process_command_line->AppendSwitch(switches::kStartStackProfiler);
}
}
......@@ -167,8 +164,9 @@ ThreadProfilerConfiguration::ChooseConfiguration(
// static
ThreadProfilerConfiguration::ProfileConfiguration
ThreadProfilerConfiguration::GenerateConfiguration(
metrics::CallStackProfileParams::Process process,
const ThreadProfilerPlatformConfiguration& platform_configuration) {
if (!IsBrowserProcess())
if (process != metrics::CallStackProfileParams::BROWSER_PROCESS)
return PROFILE_FROM_COMMAND_LINE;
const version_info::Channel channel = chrome::GetChannel();
......
......@@ -10,6 +10,7 @@
#include "base/callback.h"
#include "base/macros.h"
#include "base/profiler/stack_sampling_profiler.h"
#include "components/metrics/call_stack_profile_params.h"
namespace base {
class CommandLine;
......@@ -75,11 +76,16 @@ class ThreadProfilerConfiguration {
// Generates sampling profiler configurations for all processes.
static ProfileConfiguration GenerateConfiguration(
metrics::CallStackProfileParams::Process process,
const ThreadProfilerPlatformConfiguration& platform_configuration);
// NOTE: all state in this class must be const and initialized at 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>
platform_configuration_;
......
......@@ -7,18 +7,12 @@
#include "base/command_line.h"
#include "base/profiler/stack_sampling_profiler.h"
#include "build/build_config.h"
#include "content/public/common/content_switches.h"
#include "extensions/buildflags/buildflags.h"
#include "sandbox/policy/sandbox.h"
#include "chrome/common/profiler/process_type.h"
#if defined(OS_ANDROID)
#include "chrome/android/modules/stack_unwinder/public/module.h"
#endif
#if BUILDFLAG(ENABLE_EXTENSIONS)
#include "extensions/common/switches.h"
#endif
namespace {
// The default configuration to use in the absence of special circumstances on a
......@@ -38,15 +32,12 @@ class DefaultPlatformConfiguration
version_info::Channel channel) const override;
double GetChildProcessEnableFraction(
const base::CommandLine& child_process_command_line) const override;
metrics::CallStackProfileParams::Process process) const override;
protected:
bool IsSupportedForChannel(bool is_chrome_branded,
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_; }
private:
......@@ -85,30 +76,25 @@ DefaultPlatformConfiguration::GetEnableRates(
}
double DefaultPlatformConfiguration::GetChildProcessEnableFraction(
const base::CommandLine& child_process_command_line) const {
const std::string& process_type =
child_process_command_line.GetSwitchValueASCII(switches::kProcessType);
if (process_type == switches::kGpuProcess)
return 1.0;
metrics::CallStackProfileParams::Process process) const {
DCHECK_NE(metrics::CallStackProfileParams::BROWSER_PROCESS, process);
// The network service is the only utility process that is profiled for now.
if (process_type == switches::kUtilityProcess &&
sandbox::policy::SandboxTypeFromCommandLine(child_process_command_line) ==
sandbox::policy::SandboxType::kNetwork) {
switch (process) {
case metrics::CallStackProfileParams::GPU_PROCESS:
case metrics::CallStackProfileParams::NETWORK_SERVICE_PROCESS:
return 1.0;
}
break;
// Only start the profiler for non-extension renderer processes.
if (process_type == switches::kRendererProcess &&
!IsExtensionRenderer(child_process_command_line)) {
case metrics::CallStackProfileParams::RENDERER_PROCESS:
// 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;
}
break;
default:
return 0.0;
}
}
bool DefaultPlatformConfiguration::IsSupportedForChannel(
......@@ -124,23 +110,7 @@ bool DefaultPlatformConfiguration::IsSupportedForChannel(
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)
bool IsBrowserProcess() {
return base::CommandLine::ForCurrentProcess()
->GetSwitchValueASCII(switches::kProcessType)
.empty();
}
// The configuration to use for the Android platform. Applies to ARM32 which is
// the only Android architecture currently supported by StackSamplingProfiler.
// Defined in terms of DefaultPlatformConfiguration where Android does not
......@@ -157,7 +127,7 @@ class AndroidPlatformConfiguration : public DefaultPlatformConfiguration {
void RequestRuntimeModuleInstall() const override;
double GetChildProcessEnableFraction(
const base::CommandLine& child_process_command_line) const override;
metrics::CallStackProfileParams::Process process) const override;
protected:
bool IsSupportedForChannel(bool is_chrome_branded,
......@@ -201,7 +171,8 @@ AndroidPlatformConfiguration::GetRuntimeModuleState(
void AndroidPlatformConfiguration::RequestRuntimeModuleInstall() const {
// 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
// run of Chrome following install.
......@@ -209,13 +180,11 @@ void AndroidPlatformConfiguration::RequestRuntimeModuleInstall() const {
}
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
// otherwise.
if (browser_test_mode_enabled()) {
return DefaultPlatformConfiguration::GetChildProcessEnableFraction(
child_process_command_line);
}
if (browser_test_mode_enabled())
return DefaultPlatformConfiguration::GetChildProcessEnableFraction(process);
// TODO(https://crbug.com/1004855): Enable for all the default processes.
return 0.0;
......
......@@ -7,12 +7,9 @@
#include <memory>
#include "components/metrics/call_stack_profile_params.h"
#include "components/version_info/version_info.h"
namespace base {
class CommandLine;
}
// Encapsulates the platform-specific configuration for the ThreadProfiler.
//
// The interface functions this class make a distinction between 'supported' and
......@@ -80,10 +77,9 @@ class ThreadProfilerPlatformConfiguration {
version_info::Channel channel) const = 0;
// 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
// return value is in the range [0.0, 1.0].
// for the child |process|. The return value is in the range [0.0, 1.0].
virtual double GetChildProcessEnableFraction(
const base::CommandLine& child_process_command_line) const = 0;
metrics::CallStackProfileParams::Process process) const = 0;
protected:
// True if the profiler is to be run for the channel/chrome branding on the
......
......@@ -6,20 +6,11 @@
#include <utility>
#include "base/command_line.h"
#include "base/profiler/profiler_buildflags.h"
#include "build/build_config.h"
#include "chrome/common/chrome_switches.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"
#if BUILDFLAG(ENABLE_EXTENSIONS)
#include "extensions/common/switches.h"
#endif
#if (defined(OS_WIN) && defined(ARCH_CPU_X86_64)) || \
(defined(OS_MAC) && defined(ARCH_CPU_X86_64)) || \
(defined(OS_ANDROID) && BUILDFLAG(ENABLE_ARM_CFI_TABLE))
......@@ -52,30 +43,6 @@ class ThreadProfilerPlatformConfigurationTest : public ::testing::Test {
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
// Glue functions to make RelativePopulations work with googletest.
......@@ -214,64 +181,26 @@ MAYBE_PLATFORM_CONFIG_TEST_F(ThreadProfilerPlatformConfigurationTest,
MAYBE_PLATFORM_CONFIG_TEST_F(ThreadProfilerPlatformConfigurationTest,
GetChildProcessEnableFraction) {
#if defined(OS_ANDROID)
WithSwitches(
{Switch(switches::kProcessType, switches::kGpuProcess)},
[this](const base::CommandLine command_line) {
EXPECT_EQ(0.0, config()->GetChildProcessEnableFraction(command_line));
});
WithSwitches(
{Switch(switches::kProcessType, switches::kUtilityProcess),
Switch(sandbox::policy::switches::kServiceSandboxType,
sandbox::policy::switches::kNetworkSandbox)},
[this](const base::CommandLine command_line) {
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));
});
EXPECT_EQ(0.0, config()->GetChildProcessEnableFraction(
metrics::CallStackProfileParams::GPU_PROCESS));
EXPECT_EQ(0.0, config()->GetChildProcessEnableFraction(
metrics::CallStackProfileParams::RENDERER_PROCESS));
EXPECT_EQ(0.0, config()->GetChildProcessEnableFraction(
metrics::CallStackProfileParams::NETWORK_SERVICE_PROCESS));
EXPECT_EQ(0.0, config()->GetChildProcessEnableFraction(
metrics::CallStackProfileParams::UTILITY_PROCESS));
EXPECT_EQ(0.0, config()->GetChildProcessEnableFraction(
metrics::CallStackProfileParams::UNKNOWN_PROCESS));
#else
WithSwitches(
{Switch(switches::kProcessType, switches::kGpuProcess)},
[this](const base::CommandLine command_line) {
EXPECT_EQ(1.0, config()->GetChildProcessEnableFraction(command_line));
});
WithSwitches(
{Switch(switches::kProcessType, switches::kUtilityProcess),
Switch(sandbox::policy::switches::kServiceSandboxType,
sandbox::policy::switches::kNetworkSandbox)},
[this](const base::CommandLine command_line) {
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));
});
EXPECT_EQ(1.0, config()->GetChildProcessEnableFraction(
metrics::CallStackProfileParams::GPU_PROCESS));
EXPECT_EQ(0.2, config()->GetChildProcessEnableFraction(
metrics::CallStackProfileParams::RENDERER_PROCESS));
EXPECT_EQ(1.0, config()->GetChildProcessEnableFraction(
metrics::CallStackProfileParams::NETWORK_SERVICE_PROCESS));
EXPECT_EQ(0.0, config()->GetChildProcessEnableFraction(
metrics::CallStackProfileParams::UTILITY_PROCESS));
EXPECT_EQ(0.0, config()->GetChildProcessEnableFraction(
metrics::CallStackProfileParams::UNKNOWN_PROCESS));
#endif
}
......@@ -3777,8 +3777,6 @@ test("unit_tests") {
"../common/mac/mock_launchd.mm",
"../common/net/safe_search_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",
"../renderer/chrome_content_renderer_client_unittest.cc",
"../renderer/chrome_render_frame_observer_unittest.cc",
......@@ -4006,6 +4004,7 @@ test("unit_tests") {
"//chrome/browser/video_tutorials:unit_tests",
"//chrome/common:test_support",
"//chrome/common/privacy_budget:unit_tests",
"//chrome/common/profiler:unit_tests",
"//chrome/services/machine_learning:unit_tests",
"//chrome/services/machine_learning/public/cpp:test_support",
"//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