Skip to content

Commit

Permalink
Add support for CPU profiling in headless_shell.
Browse files Browse the repository at this point in the history
This CL factors CPU profiling code out of chrome/ and into content/ to support
CPU profiling Headless Chromium.  headless_content_main_delegate.cc has been
modified to honor CPU profiling flags à la chrome_main_delegate.cc.

Bug: 890456
Change-Id: I76842c5936de82d6bd42354c461aff9e0d273248
Reviewed-on: https://chromium-review.googlesource.com/c/1312157
Commit-Queue: Bryce Thomas <[email protected]>
Reviewed-by: Dmitry Gozman <[email protected]>
Reviewed-by: Avi Drissman <[email protected]>
Reviewed-by: Daniel Cheng <[email protected]>
Reviewed-by: Stefan Zager <[email protected]>
Cr-Commit-Position: refs/heads/master@{#605942}
  • Loading branch information
Bryce Thomas authored and Commit Bot committed Nov 7, 2018
1 parent 6188dcc commit 96b0777
Show file tree
Hide file tree
Showing 17 changed files with 80 additions and 46 deletions.
11 changes: 11 additions & 0 deletions base/base_switches.cc
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,11 @@ const char kTraceToFile[] = "trace-to-file";
// go to a default file name.
const char kTraceToFileName[] = "trace-to-file-name";

// Starts the sampling based profiler for the browser process at startup. This
// will only work if chrome has been built with the gn arg enable_profiling =
// true. The output will go to the value of kProfilingFile.
const char kProfilingAtStart[] = "profiling-at-start";

// Specifies a location for profiling output. This will only work if chrome has
// been built with the gyp variable profiling=1 or gn arg enable_profiling=true.
//
Expand All @@ -91,6 +96,12 @@ const char kTraceToFileName[] = "trace-to-file-name";
// for tests.
const char kProfilingFile[] = "profiling-file";

// Controls whether profile data is periodically flushed to a file. Normally
// the data gets written on exit but cases exist where chromium doesn't exit
// cleanly (especially when using single-process). A time in seconds can be
// specified.
const char kProfilingFlush[] = "profiling-flush";

#if defined(OS_WIN)
// Disables the USB keyboard detection for blocking the OSK on Win8+.
const char kDisableUsbKeyboardDetect[] = "disable-usb-keyboard-detect";
Expand Down
2 changes: 2 additions & 0 deletions base/base_switches.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ extern const char kEnableLowEndDeviceMode[];
extern const char kForceFieldTrials[];
extern const char kFullMemoryCrashReport[];
extern const char kNoErrorDialogs[];
extern const char kProfilingAtStart[];
extern const char kProfilingFile[];
extern const char kProfilingFlush[];
extern const char kTestChildProcess[];
extern const char kTestDoNotInitializeIcu[];
extern const char kTraceToFile[];
Expand Down
10 changes: 5 additions & 5 deletions chrome/app/chrome_main_delegate.cc
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
#include "chrome/common/chrome_switches.h"
#include "chrome/common/crash_keys.h"
#include "chrome/common/logging_chrome.h"
#include "chrome/common/profiling.h"
#include "chrome/common/trace_event_args_whitelist.h"
#include "chrome/common/url_constants.h"
#include "chrome/gpu/chrome_content_gpu_client.h"
Expand All @@ -55,6 +54,7 @@
#include "content/public/common/content_client.h"
#include "content/public/common/content_paths.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/profiling.h"
#include "content/public/common/service_names.mojom.h"
#include "extensions/common/constants.h"
#include "net/url_request/url_request.h"
Expand Down Expand Up @@ -352,7 +352,7 @@ void HandleHelpSwitches(const base::CommandLine& command_line) {

#if !defined(OS_MACOSX) && !defined(OS_ANDROID)
void SIGTERMProfilingShutdown(int signal) {
Profiling::Stop();
content::Profiling::Stop();
struct sigaction sigact;
memset(&sigact, 0, sizeof(sigact));
sigact.sa_handler = SIG_DFL;
Expand Down Expand Up @@ -556,7 +556,7 @@ bool ChromeMainDelegate::BasicStartupComplete(int* exit_code) {
chrome::common::mac::EnableCFBundleBlocker();
#endif

Profiling::ProcessStarted();
content::Profiling::ProcessStarted();

base::trace_event::TraceLog::GetInstance()->SetArgumentFilterPredicate(
base::Bind(&IsTraceEventArgsWhitelisted));
Expand Down Expand Up @@ -1055,8 +1055,8 @@ void ChromeMainDelegate::ZygoteStarting(
}

void ChromeMainDelegate::ZygoteForked() {
Profiling::ProcessStarted();
if (Profiling::BeingProfiled()) {
content::Profiling::ProcessStarted();
if (content::Profiling::BeingProfiled()) {
base::debug::RestartProfilingAfterFork();
SetUpProfilingShutdownHandler();
}
Expand Down
2 changes: 1 addition & 1 deletion chrome/browser/chrome_browser_main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,6 @@
#include "chrome/common/media/media_resource_provider.h"
#include "chrome/common/net/net_resource_provider.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/profiling.h"
#include "chrome/common/stack_sampling_configuration.h"
#include "chrome/common/thread_profiler.h"
#include "chrome/grit/generated_resources.h"
Expand Down Expand Up @@ -176,6 +175,7 @@
#include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/main_function_params.h"
#include "content/public/common/profiling.h"
#include "content/public/common/service_manager_connection.h"
#include "device/vr/buildflags/buildflags.h"
#include "extensions/buildflags/buildflags.h"
Expand Down
9 changes: 0 additions & 9 deletions chrome/browser/chrome_content_browser_client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2114,9 +2114,6 @@ void ChromeContentBrowserClient::AppendExtraCommandLineSwitches(
switches::kPpapiFlashArgs,
switches::kPpapiFlashPath,
switches::kPpapiFlashVersion,
switches::kProfilingAtStart,
switches::kProfilingFile,
switches::kProfilingFlush,
switches::kReaderModeHeuristics,
translate::switches::kTranslateSecurityOrigin,
};
Expand Down Expand Up @@ -2157,12 +2154,6 @@ void ChromeContentBrowserClient::AppendExtraCommandLineSwitches(
if (browser_command_line.HasSwitch(switches::kIgnoreGpuBlacklist) &&
!command_line->HasSwitch(switches::kDisableBreakpad))
command_line->AppendSwitch(switches::kDisableBreakpad);
static const char* const kSwitchNames[] = {
switches::kProfilingAtStart, switches::kProfilingFile,
switches::kProfilingFlush,
};
command_line->CopySwitchesFrom(browser_command_line, kSwitchNames,
base::size(kSwitchNames));
}

StackSamplingConfiguration::Get()->AppendCommandLineSwitchForChildProcess(
Expand Down
2 changes: 1 addition & 1 deletion chrome/browser/ui/browser.cc
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,6 @@
#include "chrome/common/chrome_switches.h"
#include "chrome/common/custom_handlers/protocol_handler.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/profiling.h"
#include "chrome/common/ssl_insecure_content.h"
#include "chrome/common/url_constants.h"
#include "chrome/grit/chromium_strings.h"
Expand Down Expand Up @@ -200,6 +199,7 @@
#include "content/public/common/content_constants.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/page_zoom.h"
#include "content/public/common/profiling.h"
#include "content/public/common/renderer_preferences.h"
#include "content/public/common/webplugininfo.h"
#include "extensions/browser/extension_prefs.h"
Expand Down
4 changes: 2 additions & 2 deletions chrome/browser/ui/browser_command_controller.cc
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@
#include "chrome/browser/ui/webui/inspect_ui.h"
#include "chrome/common/content_restriction.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/profiling.h"
#include "chrome/common/url_constants.h"
#include "components/bookmarks/common/bookmark_pref_names.h"
#include "components/dom_distiller/core/dom_distiller_switches.h"
Expand All @@ -58,6 +57,7 @@
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/common/profiling.h"
#include "content/public/common/service_manager_connection.h"
#include "content/public/common/url_constants.h"
#include "extensions/browser/extension_system.h"
Expand Down Expand Up @@ -608,7 +608,7 @@ bool BrowserCommandController::ExecuteCommandWithDisposition(
ToggleBookmarkBar(browser_);
break;
case IDC_PROFILING_ENABLED:
Profiling::Toggle();
content::Profiling::Toggle();
break;

case IDC_SHOW_BOOKMARK_MANAGER:
Expand Down
4 changes: 2 additions & 2 deletions chrome/browser/ui/toolbar/app_menu_model.cc
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/profiling.h"
#include "chrome/grit/chromium_strings.h"
#include "chrome/grit/generated_resources.h"
#include "chrome/grit/theme_resources.h"
Expand All @@ -63,6 +62,7 @@
#include "content/public/browser/notification_source.h"
#include "content/public/browser/notification_types.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/profiling.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/layout.h"
#include "ui/base/models/button_menu_item_model.h"
Expand Down Expand Up @@ -629,7 +629,7 @@ bool AppMenuModel::IsCommandIdChecked(int command_id) const {
bookmarks::prefs::kShowBookmarkBar);
}
if (command_id == IDC_PROFILING_ENABLED)
return Profiling::BeingProfiled();
return content::Profiling::BeingProfiled();
if (command_id == IDC_TOGGLE_REQUEST_TABLET_SITE)
return chrome::IsRequestingTabletSite(browser_);

Expand Down
2 changes: 0 additions & 2 deletions chrome/common/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -175,8 +175,6 @@ static_library("common") {
"prerender_url_loader_throttle.h",
"prerender_util.cc",
"prerender_util.h",
"profiling.cc",
"profiling.h",
"ref_counted_util.h",
"render_messages.h",
"search/instant_types.cc",
Expand Down
11 changes: 0 additions & 11 deletions chrome/common/chrome_switches.cc
Original file line number Diff line number Diff line change
Expand Up @@ -550,17 +550,6 @@ const char kProductVersion[] = "product-version";
// Selects directory of profile to associate with the first browser launched.
const char kProfileDirectory[] = "profile-directory";

// Starts the sampling based profiler for the browser process at startup. This
// will only work if chrome has been built with the gyp variable profiling=1.
// The output will go to the value of kProfilingFile.
const char kProfilingAtStart[] = "profiling-at-start";

// Controls whether profile data is periodically flushed to a file. Normally
// the data gets written on exit but cases exist where chrome doesn't exit
// cleanly (especially when using single-process). A time in seconds can be
// specified.
const char kProfilingFlush[] = "profiling-flush";

// Forces proxy auto-detection.
const char kProxyAutoDetect[] = "proxy-auto-detect";

Expand Down
2 changes: 0 additions & 2 deletions chrome/common/chrome_switches.h
Original file line number Diff line number Diff line change
Expand Up @@ -164,8 +164,6 @@ extern const char kPpapiFlashVersion[];
extern const char kPrivetIPv6Only[];
extern const char kProductVersion[];
extern const char kProfileDirectory[];
extern const char kProfilingAtStart[];
extern const char kProfilingFlush[];
extern const char kProxyAutoDetect[];
extern const char kProxyBypassList[];
extern const char kProxyPacUrl[];
Expand Down
3 changes: 3 additions & 0 deletions content/browser/gpu/gpu_process_host.cc
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,9 @@ static const char* const kSwitchNames[] = {
switches::kLoggingLevel,
switches::kEnableLowEndDeviceMode,
switches::kDisableLowEndDeviceMode,
switches::kProfilingAtStart,
switches::kProfilingFile,
switches::kProfilingFlush,
switches::kRunAllCompositorStagesBeforeDraw,
switches::kSkiaFontCacheLimitMb,
switches::kSkiaResourceCacheLimitMb,
Expand Down
3 changes: 3 additions & 0 deletions content/browser/renderer_host/render_process_host_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3048,6 +3048,9 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer(
switches::kOverridePluginPowerSaverForTesting,
switches::kPassiveListenersDefault,
switches::kPpapiInProcess,
switches::kProfilingAtStart,
switches::kProfilingFile,
switches::kProfilingFlush,
switches::kReducedReferrerGranularity,
switches::kRegisterPepperPlugins,
switches::kRendererStartupDialog,
Expand Down
2 changes: 2 additions & 0 deletions content/public/common/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,8 @@ jumbo_source_set("common_sources") {
"persistent_notification_status.h",
"previews_state.h",
"process_type.h",
"profiling.cc",
"profiling.h",
"push_subscription_options.h",
"referrer.cc",
"referrer.h",
Expand Down
17 changes: 10 additions & 7 deletions chrome/common/profiling.cc → content/public/common/profiling.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/common/profiling.h"
#include "content/public/common/profiling.h"

#include "base/at_exit.h"
#include "base/base_switches.h"
Expand All @@ -16,9 +16,10 @@
#include "base/single_thread_task_runner.h"
#include "base/strings/string_util.h"
#include "base/threading/thread.h"
#include "chrome/common/chrome_switches.h"
#include "content/public/common/content_switches.h"

namespace content {

namespace {

std::string GetProfileName() {
Expand All @@ -33,8 +34,8 @@ std::string GetProfileName() {
profile_name = std::string("chrome-profile-{type}-{pid}");
std::string process_type =
command_line.GetSwitchValueASCII(switches::kProcessType);
std::string type = process_type.empty() ?
std::string("browser") : std::string(process_type);
std::string type = process_type.empty() ? std::string("browser")
: std::string(process_type);
base::ReplaceSubstringsAfterOffset(&profile_name, 0, "{type}", type);

return profile_name;
Expand Down Expand Up @@ -100,10 +101,10 @@ class ProfilingThreadControl {
DISALLOW_COPY_AND_ASSIGN(ProfilingThreadControl);
};

base::LazyInstance<ProfilingThreadControl>::Leaky
g_flush_thread_control = LAZY_INSTANCE_INITIALIZER;
base::LazyInstance<ProfilingThreadControl>::Leaky g_flush_thread_control =
LAZY_INSTANCE_INITIALIZER;

} // namespace
} // namespace

// static
void Profiling::ProcessStarted() {
Expand Down Expand Up @@ -151,3 +152,5 @@ void Profiling::Toggle() {
else
Start();
}

} // namespace content
13 changes: 9 additions & 4 deletions chrome/common/profiling.h → content/public/common/profiling.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,22 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_COMMON_PROFILING_H_
#define CHROME_COMMON_PROFILING_H_
#ifndef CONTENT_PUBLIC_COMMON_PROFILING_H_
#define CONTENT_PUBLIC_COMMON_PROFILING_H_

#include "build/build_config.h"

#include "base/debug/profiler.h"
#include "base/macros.h"
#include "content/common/content_export.h"

namespace content {

// The Profiling class manages the interaction with a sampling based profiler.
// Its function is controlled by the kProfilingAtStart, kProfilingFile, and
// kProfilingFlush command line values.
// All of the API should only be called from the main thread of the process.
class Profiling {
class CONTENT_EXPORT Profiling {
public:
// Called early in a process' life to allow profiling of startup time.
// the presence of kProfilingAtStart is checked.
Expand All @@ -39,4 +42,6 @@ class Profiling {
DISALLOW_COPY_AND_ASSIGN(Profiling);
};

#endif // CHROME_COMMON_PROFILING_H_
} // namespace content

#endif // CONTENT_PUBLIC_COMMON_PROFILING_H_
29 changes: 29 additions & 0 deletions headless/lib/headless_content_main_delegate.cc
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "components/crash/core/common/crash_key.h"
#include "content/public/browser/browser_main_runner.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/profiling.h"
#include "headless/lib/browser/headless_browser_impl.h"
#include "headless/lib/browser/headless_content_browser_client.h"
#include "headless/lib/headless_crash_reporter_client.h"
Expand All @@ -48,6 +49,10 @@
#include "headless/lib/renderer/headless_content_renderer_client.h"
#endif

#if defined(OS_POSIX)
#include <signal.h>
#endif

namespace headless {
namespace {
// Keep in sync with content/common/content_constants_internal.h.
Expand Down Expand Up @@ -123,6 +128,8 @@ bool HeadlessContentMainDelegate::BasicStartupComplete(int* exit_code) {
// preempt this attempt.
command_line->AppendSwitch(::switches::kDisableGpuCompositing);

content::Profiling::ProcessStarted();

SetContentClient(&content_client_);
return false;
}
Expand Down Expand Up @@ -291,7 +298,29 @@ int HeadlessContentMainDelegate::RunProcess(
#endif // !defined(CHROME_MULTIPLE_DLL_CHILD)

#if defined(OS_LINUX)
void SIGTERMProfilingShutdown(int signal) {
content::Profiling::Stop();
struct sigaction sigact;
memset(&sigact, 0, sizeof(sigact));
sigact.sa_handler = SIG_DFL;
CHECK_EQ(sigaction(SIGTERM, &sigact, NULL), 0);
raise(signal);
}

void SetUpProfilingShutdownHandler() {
struct sigaction sigact;
sigact.sa_handler = SIGTERMProfilingShutdown;
sigact.sa_flags = SA_RESETHAND;
sigemptyset(&sigact.sa_mask);
CHECK_EQ(sigaction(SIGTERM, &sigact, NULL), 0);
}

void HeadlessContentMainDelegate::ZygoteForked() {
content::Profiling::ProcessStarted();
if (content::Profiling::BeingProfiled()) {
base::debug::RestartProfilingAfterFork();
SetUpProfilingShutdownHandler();
}
const base::CommandLine& command_line(
*base::CommandLine::ForCurrentProcess());
const std::string process_type =
Expand Down

0 comments on commit 96b0777

Please sign in to comment.