Commit eeea9224 authored by Takashi Sakamoto's avatar Takashi Sakamoto Committed by Commit Bot

Fix CrashMemoryMetricsReporterImpl to report memory usage upon renderer OOM crash

Change-Id: I5a96979b123311ed5aa4dda35c39d1eaa7bc98da
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1975377
Commit-Queue: Takashi Sakamoto <tasak@google.com>
Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Reviewed-by: default avatarErik Chen <erikchen@chromium.org>
Cr-Commit-Position: refs/heads/master@{#731863}
parent e6beeda6
...@@ -16,17 +16,17 @@ namespace blink { ...@@ -16,17 +16,17 @@ namespace blink {
// the arm64 and renderer in the arm32. // the arm64 and renderer in the arm32.
struct OomInterventionMetrics { struct OomInterventionMetrics {
uint64_t current_private_footprint_kb; uint64_t current_private_footprint_kb = 0;
uint64_t current_swap_kb; uint64_t current_swap_kb = 0;
uint64_t current_vm_size_kb; uint64_t current_vm_size_kb = 0;
// Stores the total of V8, BlinkGC and PartitionAlloc memory usage. // Stores the total of V8, BlinkGC and PartitionAlloc memory usage.
uint64_t current_blink_usage_kb; uint64_t current_blink_usage_kb = 0;
// Indicates whether the crash was because of virtual address space OOM. // Indicates whether the crash was because of virtual address space OOM.
// This holds only 0 or 1 as a value but because of the reason stated above, // This holds only 0 or 1 as a value but because of the reason stated above,
// uses uint64_t instead of boolean. // uses uint64_t instead of boolean.
uint64_t allocation_failed; uint64_t allocation_failed = 0;
}; };
} // namespace blink } // namespace blink
......
...@@ -37,50 +37,54 @@ CrashMemoryMetricsReporterImpl::CrashMemoryMetricsReporterImpl() { ...@@ -37,50 +37,54 @@ CrashMemoryMetricsReporterImpl::CrashMemoryMetricsReporterImpl() {
CrashMemoryMetricsReporterImpl::OnOOMCallback); CrashMemoryMetricsReporterImpl::OnOOMCallback);
} }
CrashMemoryMetricsReporterImpl::~CrashMemoryMetricsReporterImpl() = default; CrashMemoryMetricsReporterImpl::~CrashMemoryMetricsReporterImpl() {
MemoryUsageMonitor::Instance().RemoveObserver(this);
}
void CrashMemoryMetricsReporterImpl::SetSharedMemory( void CrashMemoryMetricsReporterImpl::SetSharedMemory(
base::UnsafeSharedMemoryRegion shared_metrics_buffer) { base::UnsafeSharedMemoryRegion shared_metrics_buffer) {
// This method should be called only once per process. // This method should be called only once per process.
DCHECK(!shared_metrics_mapping_.IsValid()); DCHECK(!shared_metrics_mapping_.IsValid());
shared_metrics_mapping_ = shared_metrics_buffer.Map(); shared_metrics_mapping_ = shared_metrics_buffer.Map();
MemoryUsageMonitor::Instance().AddObserver(this);
} }
void CrashMemoryMetricsReporterImpl::OnMemoryPing(MemoryUsage usage) { void CrashMemoryMetricsReporterImpl::OnMemoryPing(MemoryUsage usage) {
WriteIntoSharedMemory( DCHECK(IsMainThread());
CrashMemoryMetricsReporterImpl::MemoryUsageToMetrics(usage)); last_reported_metrics_ =
CrashMemoryMetricsReporterImpl::MemoryUsageToMetrics(usage);
WriteIntoSharedMemory();
} }
void CrashMemoryMetricsReporterImpl::WriteIntoSharedMemory( void CrashMemoryMetricsReporterImpl::WriteIntoSharedMemory() {
const OomInterventionMetrics& metrics) {
if (!shared_metrics_mapping_.IsValid()) if (!shared_metrics_mapping_.IsValid())
return; return;
auto* metrics_shared = auto* metrics_shared =
shared_metrics_mapping_.GetMemoryAs<OomInterventionMetrics>(); shared_metrics_mapping_.GetMemoryAs<OomInterventionMetrics>();
memcpy(metrics_shared, &metrics, sizeof(OomInterventionMetrics)); *metrics_shared = last_reported_metrics_;
} }
void CrashMemoryMetricsReporterImpl::OnOOMCallback() { void CrashMemoryMetricsReporterImpl::OnOOMCallback() {
// TODO(yuzus: Support allocation failures on other threads as well. // TODO(yuzus: Support allocation failures on other threads as well.
if (!IsMainThread()) if (!IsMainThread())
return; return;
CrashMemoryMetricsReporterImpl& instance =
CrashMemoryMetricsReporterImpl::Instance();
// If shared_metrics_mapping_ is not set, it means OnNoMemory happened before // If shared_metrics_mapping_ is not set, it means OnNoMemory happened before
// initializing render process host sets the shared memory. // initializing render process host sets the shared memory.
if (!CrashMemoryMetricsReporterImpl::Instance() if (!instance.shared_metrics_mapping_.IsValid())
.shared_metrics_mapping_.IsValid())
return; return;
// Else, we can send the allocation_failed bool. // Else, we can send the allocation_failed bool.
OomInterventionMetrics metrics;
// TODO(yuzus): Report this UMA on all the platforms. Currently this is only // TODO(yuzus): Report this UMA on all the platforms. Currently this is only
// reported on Android. // reported on Android.
metrics.allocation_failed = 1; // true instance.last_reported_metrics_.allocation_failed = 1; // true
CrashMemoryMetricsReporterImpl::Instance().WriteIntoSharedMemory(metrics); instance.WriteIntoSharedMemory();
} }
// static // static
OomInterventionMetrics CrashMemoryMetricsReporterImpl::MemoryUsageToMetrics( OomInterventionMetrics CrashMemoryMetricsReporterImpl::MemoryUsageToMetrics(
MemoryUsage usage) { MemoryUsage usage) {
OomInterventionMetrics metrics = {}; OomInterventionMetrics metrics;
DCHECK(!std::isnan(usage.private_footprint_bytes)); DCHECK(!std::isnan(usage.private_footprint_bytes));
DCHECK(!std::isnan(usage.swap_bytes)); DCHECK(!std::isnan(usage.swap_bytes));
......
...@@ -31,9 +31,6 @@ class CONTROLLER_EXPORT CrashMemoryMetricsReporterImpl ...@@ -31,9 +31,6 @@ class CONTROLLER_EXPORT CrashMemoryMetricsReporterImpl
void SetSharedMemory( void SetSharedMemory(
base::UnsafeSharedMemoryRegion shared_metrics_buffer) override; base::UnsafeSharedMemoryRegion shared_metrics_buffer) override;
// MemoryUsageMonitor::Observer:
void OnMemoryPing(MemoryUsage) override;
// This method tracks when an allocation failure occurs. It should be hooked // This method tracks when an allocation failure occurs. It should be hooked
// into all platform allocation failure handlers in a process such as // into all platform allocation failure handlers in a process such as
// base::TerminateBecauseOutOfMemory() and OOM_CRASH() in Partition Alloc. // base::TerminateBecauseOutOfMemory() and OOM_CRASH() in Partition Alloc.
...@@ -47,8 +44,12 @@ class CONTROLLER_EXPORT CrashMemoryMetricsReporterImpl ...@@ -47,8 +44,12 @@ class CONTROLLER_EXPORT CrashMemoryMetricsReporterImpl
private: private:
FRIEND_TEST_ALL_PREFIXES(OomInterventionImplTest, CalculateProcessFootprint); FRIEND_TEST_ALL_PREFIXES(OomInterventionImplTest, CalculateProcessFootprint);
void WriteIntoSharedMemory(const OomInterventionMetrics& metrics); // MemoryUsageMonitor::Observer:
void OnMemoryPing(MemoryUsage) override;
void WriteIntoSharedMemory();
OomInterventionMetrics last_reported_metrics_;
base::WritableSharedMemoryMapping shared_metrics_mapping_; base::WritableSharedMemoryMapping shared_metrics_mapping_;
mojo::Receiver<mojom::blink::CrashMemoryMetricsReporter> receiver_{this}; mojo::Receiver<mojom::blink::CrashMemoryMetricsReporter> receiver_{this};
}; };
......
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