| Index: chrome/browser/metrics/leak_detector/leak_detector_controller.cc
|
| diff --git a/chrome/browser/metrics/leak_detector/leak_detector_controller.cc b/chrome/browser/metrics/leak_detector/leak_detector_controller.cc
|
| index 898dd066fd0942b29dcc89e72037955fce393db0..dbe2577f4428ba222dad8543d59a2675a5201dbf 100644
|
| --- a/chrome/browser/metrics/leak_detector/leak_detector_controller.cc
|
| +++ b/chrome/browser/metrics/leak_detector/leak_detector_controller.cc
|
| @@ -7,6 +7,7 @@
|
| #include <algorithm>
|
|
|
| #include "base/logging.h"
|
| +#include "base/rand_util.h"
|
| #include "base/strings/string_number_conversions.h"
|
| #include "components/metrics/leak_detector/gnu_build_id_reader.h"
|
| #include "components/variations/variations_associated_data.h"
|
| @@ -16,12 +17,24 @@ namespace metrics {
|
|
|
| namespace {
|
|
|
| -// Reads parameters for the field trial variation. Any parameters not present in
|
| -// the variation info or that cannot be parsed will be filled in with default
|
| -// values. Returns a MemoryLeakReportProto with the parameter fields filled in.
|
| -MemoryLeakReportProto::Params GetVariationParameters() {
|
| - // Variation parameter names.
|
| +using ParamsMap = std::map<std::string, std::string>;
|
| +
|
| +// Returns a mapping of param names to param values, obtained from the
|
| +// variations system. Both names and values are strings.
|
| +ParamsMap GetRawVariationParams() {
|
| const char kFieldTrialName[] = "RuntimeMemoryLeakDetector";
|
| + ParamsMap result;
|
| + variations::GetVariationParams(kFieldTrialName, &result);
|
| + return result;
|
| +}
|
| +
|
| +// Reads the raw variation parameters and parses them to obtain values for the
|
| +// parameters used by the memory leak detector itself. Any parameters not
|
| +// present in the variation info or that cannot be parsed will be filled in with
|
| +// default values. Returns a MemoryLeakReportProto with the parameter fields
|
| +// filled in.
|
| +MemoryLeakReportProto::Params GetLeakDetectorParams() {
|
| + // Variation parameter names.
|
| const char kSamplingRateParam[] = "sampling_rate";
|
| const char kMaxStackDepthParam[] = "max_stack_depth";
|
| const char kAnalysisIntervalKbParam[] = "analysis_interval_kb";
|
| @@ -42,9 +55,7 @@ MemoryLeakReportProto::Params GetVariationParameters() {
|
| uint32_t size_suspicion_threshold = 0;
|
| uint32_t call_stack_suspicion_threshold = 0;
|
|
|
| - // Get a mapping of param names to param values.
|
| - std::map<std::string, std::string> params;
|
| - variations::GetVariationParams(kFieldTrialName, ¶ms);
|
| + const ParamsMap params = GetRawVariationParams();
|
|
|
| // Even if the variation param data does not exist and |params| ends up empty,
|
| // the below code will assign default values.
|
| @@ -87,19 +98,80 @@ MemoryLeakReportProto::Params GetVariationParameters() {
|
| return result;
|
| }
|
|
|
| +// Parses the parameters related to randomly enabling leak detector on different
|
| +// processes, from the raw parameter strings provided by the variations.
|
| +// Args:
|
| +// - browser_probability: probability that the leak detector will be enabled on
|
| +// browser process (spawned once per session).
|
| +// - renderer_probability: probability that the leak detector will be enabled on
|
| +// renderer process (spawned many times per session).
|
| +// - max_renderer_processes_enabled: The maximum number of renderer processes on
|
| +// which the leak detector can be enabled
|
| +// simultaneously.
|
| +//
|
| +// Probabilities are in the range [0, 1]. Anything higher or lower will not be
|
| +// clamped but it will not affect the outcome, since these probabilities are
|
| +// compared against the value of base::RandDouble() (aka the "dice roll"), which
|
| +// will be within this range.
|
| +void GetLeakDetectorEnableParams(double* browser_probability,
|
| + double* renderer_probability,
|
| + int* max_renderer_processes_enabled) {
|
| + const char kBrowserEnableProbabilityParam[] =
|
| + "browser_process_enable_probability";
|
| + const char kRendererEnableProbabilityParam[] =
|
| + "renderer_process_enable_probability";
|
| + const char kMaxRendererProcessesEnabledParam[] =
|
| + "max_renderer_processes_enabled";
|
| + const double kDefaultProbability = 0.0;
|
| + const int kDefaultNumProcessesEnabled = 0;
|
| +
|
| + const ParamsMap params = GetRawVariationParams();
|
| + auto iter = params.find(kBrowserEnableProbabilityParam);
|
| + if (iter == params.end() ||
|
| + !base::StringToDouble(iter->second, browser_probability)) {
|
| + *browser_probability = kDefaultProbability;
|
| + }
|
| + iter = params.find(kRendererEnableProbabilityParam);
|
| + if (iter == params.end() ||
|
| + !base::StringToDouble(iter->second, renderer_probability)) {
|
| + *renderer_probability = kDefaultProbability;
|
| + }
|
| + iter = params.find(kMaxRendererProcessesEnabledParam);
|
| + if (iter == params.end() ||
|
| + !base::StringToInt(iter->second, max_renderer_processes_enabled)) {
|
| + *max_renderer_processes_enabled = kDefaultNumProcessesEnabled;
|
| + }
|
| +}
|
| +
|
| } // namespace
|
|
|
| LeakDetectorController::LeakDetectorController()
|
| - : params_(GetVariationParameters()) {
|
| + : params_(GetLeakDetectorParams()),
|
| + browser_process_enable_probability_(0),
|
| + renderer_process_enable_probability_(0),
|
| + max_renderer_processes_with_leak_detector_enabled_(0),
|
| + num_renderer_processes_with_leak_detector_enabled_(0) {
|
| // Read the build ID once and store it.
|
| leak_detector::gnu_build_id_reader::ReadBuildID(&build_id_);
|
|
|
| - LeakDetector* detector = LeakDetector::GetInstance();
|
| - detector->AddObserver(this);
|
| + GetLeakDetectorEnableParams(
|
| + &browser_process_enable_probability_,
|
| + &renderer_process_enable_probability_,
|
| + &max_renderer_processes_with_leak_detector_enabled_);
|
| +
|
| + // Register the LeakDetectorController with the remote controller, so this
|
| + // class can send/receive data to/from remote processes.
|
| + LeakDetectorRemoteController::SetLocalControllerInstance(this);
|
|
|
| - // Leak detector parameters are stored in |params_|.
|
| - detector->Init(params_, content::BrowserThread::GetTaskRunnerForThread(
|
| - content::BrowserThread::UI));
|
| + // Conditionally launch browser process based on probability.
|
| + if (base::RandDouble() < browser_process_enable_probability_) {
|
| + LeakDetector* detector = LeakDetector::GetInstance();
|
| + detector->AddObserver(this);
|
| +
|
| + // Leak detector parameters are stored in |params_|.
|
| + detector->Init(params_, content::BrowserThread::GetTaskRunnerForThread(
|
| + content::BrowserThread::UI));
|
| + }
|
| }
|
|
|
| LeakDetectorController::~LeakDetectorController() {
|
| @@ -119,8 +191,16 @@ void LeakDetectorController::OnLeaksFound(
|
| StoreLeakReports(reports, MemoryLeakReportProto::BROWSER_PROCESS);
|
| }
|
|
|
| -MemoryLeakReportProto_Params LeakDetectorController::GetParams() const {
|
| - return params_;
|
| +MemoryLeakReportProto_Params
|
| +LeakDetectorController::GetParamsAndRecordRequest() {
|
| + if (ShouldRandomlyEnableLeakDetectorOnRendererProcess()) {
|
| + ++num_renderer_processes_with_leak_detector_enabled_;
|
| + return params_;
|
| + }
|
| + // If the leak detector is not to be enabled on the remote process, send an
|
| + // empty MemoryLeakReportProto_Params protobuf. The remote process will not
|
| + // initialize the leak detector since |sampling_rate| is 0.
|
| + return MemoryLeakReportProto_Params();
|
| }
|
|
|
| void LeakDetectorController::SendLeakReports(
|
| @@ -129,7 +209,15 @@ void LeakDetectorController::SendLeakReports(
|
| }
|
|
|
| void LeakDetectorController::OnRemoteProcessShutdown() {
|
| - // TODO(sque): Handle remote process shutdown.
|
| + DCHECK_GT(num_renderer_processes_with_leak_detector_enabled_, 0);
|
| + --num_renderer_processes_with_leak_detector_enabled_;
|
| +}
|
| +
|
| +bool LeakDetectorController::ShouldRandomlyEnableLeakDetectorOnRendererProcess()
|
| + const {
|
| + return base::RandDouble() < renderer_process_enable_probability_ &&
|
| + num_renderer_processes_with_leak_detector_enabled_ <
|
| + max_renderer_processes_with_leak_detector_enabled_;
|
| }
|
|
|
| void LeakDetectorController::StoreLeakReports(
|
|
|