summaryrefslogtreecommitdiff
path: root/chromium/components/tracing
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2017-07-12 14:07:37 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2017-07-17 10:29:26 +0000
commitec02ee4181c49b61fce1c8fb99292dbb8139cc90 (patch)
tree25cde714b2b71eb639d1cd53f5a22e9ba76e14ef /chromium/components/tracing
parentbb09965444b5bb20b096a291445170876225268d (diff)
downloadqtwebengine-chromium-ec02ee4181c49b61fce1c8fb99292dbb8139cc90.tar.gz
BASELINE: Update Chromium to 59.0.3071.134
Change-Id: Id02ef6fb2204c5fd21668a1c3e6911c83b17585a Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Diffstat (limited to 'chromium/components/tracing')
-rw-r--r--chromium/components/tracing/BUILD.gn3
-rw-r--r--chromium/components/tracing/child/child_memory_dump_manager_delegate_impl.cc114
-rw-r--r--chromium/components/tracing/child/child_memory_dump_manager_delegate_impl.h85
-rw-r--r--chromium/components/tracing/child/child_trace_message_filter.cc91
-rw-r--r--chromium/components/tracing/child/child_trace_message_filter.h19
-rw-r--r--chromium/components/tracing/child/child_trace_message_filter_browsertest.cc326
-rw-r--r--chromium/components/tracing/common/process_metrics_memory_dump_provider.cc104
-rw-r--r--chromium/components/tracing/common/process_metrics_memory_dump_provider_unittest.cc23
-rw-r--r--chromium/components/tracing/common/trace_startup.cc8
-rw-r--r--chromium/components/tracing/core/proto_zero_message.cc2
-rw-r--r--chromium/components/tracing/tools/proto_zero_plugin/BUILD.gn6
11 files changed, 93 insertions, 688 deletions
diff --git a/chromium/components/tracing/BUILD.gn b/chromium/components/tracing/BUILD.gn
index deab4a66a3d..8b0bd09b7ac 100644
--- a/chromium/components/tracing/BUILD.gn
+++ b/chromium/components/tracing/BUILD.gn
@@ -7,8 +7,6 @@ import("//third_party/protobuf/proto_library.gni")
component("tracing") {
sources = [
- "child/child_memory_dump_manager_delegate_impl.cc",
- "child/child_memory_dump_manager_delegate_impl.h",
"child/child_trace_message_filter.cc",
"child/child_trace_message_filter.h",
"common/graphics_memory_dump_provider_android.cc",
@@ -101,6 +99,7 @@ source_set("unit_tests") {
"core/trace_buffer_writer_unittest.cc",
"core/trace_ring_buffer_unittest.cc",
"test/fake_scattered_buffer.cc",
+ "test/fake_scattered_buffer.h",
"test/proto_zero_generation_unittest.cc",
]
diff --git a/chromium/components/tracing/child/child_memory_dump_manager_delegate_impl.cc b/chromium/components/tracing/child/child_memory_dump_manager_delegate_impl.cc
deleted file mode 100644
index f0c4517b2ea..00000000000
--- a/chromium/components/tracing/child/child_memory_dump_manager_delegate_impl.cc
+++ /dev/null
@@ -1,114 +0,0 @@
-// Copyright 2015 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 "components/tracing/child/child_memory_dump_manager_delegate_impl.h"
-
-#include "base/single_thread_task_runner.h"
-#include "build/build_config.h"
-#include "components/tracing/child/child_trace_message_filter.h"
-#include "components/tracing/common/process_metrics_memory_dump_provider.h"
-
-namespace tracing {
-
-namespace {
-void AbortDumpRequest(const base::trace_event::MemoryDumpRequestArgs& args,
- const base::trace_event::MemoryDumpCallback& callback) {
- if (!callback.is_null())
- callback.Run(args.dump_guid, false /* success */);
-}
-} // namespace
-
-// static
-ChildMemoryDumpManagerDelegateImpl*
-ChildMemoryDumpManagerDelegateImpl::GetInstance() {
- return base::Singleton<
- ChildMemoryDumpManagerDelegateImpl,
- base::LeakySingletonTraits<ChildMemoryDumpManagerDelegateImpl>>::get();
-}
-
-ChildMemoryDumpManagerDelegateImpl::ChildMemoryDumpManagerDelegateImpl()
- : ctmf_(nullptr),
- tracing_process_id_(
- base::trace_event::MemoryDumpManager::kInvalidTracingProcessId) {
-}
-
-ChildMemoryDumpManagerDelegateImpl::~ChildMemoryDumpManagerDelegateImpl() {}
-
-void ChildMemoryDumpManagerDelegateImpl::SetChildTraceMessageFilter(
- ChildTraceMessageFilter* ctmf) {
- auto* task_runner = ctmf ? (ctmf->ipc_task_runner()) : nullptr;
- // Check that we are either registering the CTMF or tearing it down, but not
- // replacing a valid instance with another one (should never happen).
- DCHECK(!ctmf_ || (!ctmf && ctmf_task_runner_));
- ctmf_ = ctmf;
-
- {
- base::AutoLock lock(lock_);
- ctmf_task_runner_ = task_runner;
- }
-
- if (ctmf) {
- base::trace_event::MemoryDumpManager::GetInstance()->Initialize(
- this /* delegate */, false /* is_coordinator */);
-
-#if !defined(OS_LINUX) && !defined(OS_NACL)
- // On linux the browser process takes care of dumping process metrics.
- // The child process is not allowed to do so due to BPF sandbox.
- tracing::ProcessMetricsMemoryDumpProvider::RegisterForProcess(
- base::kNullProcessId);
-#endif
- }
-}
-
-// Invoked in child processes by the MemoryDumpManager.
-void ChildMemoryDumpManagerDelegateImpl::RequestGlobalMemoryDump(
- const base::trace_event::MemoryDumpRequestArgs& args,
- const base::trace_event::MemoryDumpCallback& callback) {
- // RequestGlobalMemoryDump can be called on any thread, cannot access
- // ctmf_task_runner_ as it could be racy.
- scoped_refptr<base::SingleThreadTaskRunner> ctmf_task_runner;
- {
- base::AutoLock lock(lock_);
- ctmf_task_runner = ctmf_task_runner_;
- }
-
- // Bail out if we receive a dump request from the manager before the
- // ChildTraceMessageFilter has been initialized.
- if (!ctmf_task_runner) {
- VLOG(1) << base::trace_event::MemoryDumpManager::kLogPrefix
- << " failed because child trace message filter hasn't been"
- << " initialized";
- return AbortDumpRequest(args, callback);
- }
-
- // Make sure we access |ctmf_| only on the thread where it lives to avoid
- // races on shutdown.
- if (!ctmf_task_runner->BelongsToCurrentThread()) {
- const bool did_post_task = ctmf_task_runner->PostTask(
- FROM_HERE,
- base::Bind(&ChildMemoryDumpManagerDelegateImpl::RequestGlobalMemoryDump,
- base::Unretained(this), args, callback));
- if (!did_post_task)
- return AbortDumpRequest(args, callback);
- return;
- }
-
- // The ChildTraceMessageFilter could have been destroyed while hopping on the
- // right thread. If this is the case, bail out.
- if (!ctmf_) {
- VLOG(1) << base::trace_event::MemoryDumpManager::kLogPrefix
- << " failed because child trace message filter was"
- << " destroyed while switching threads";
- return AbortDumpRequest(args, callback);
- }
-
- // Send the request up to the browser process' MessageDumpmanager.
- ctmf_->SendGlobalMemoryDumpRequest(args, callback);
-}
-
-uint64_t ChildMemoryDumpManagerDelegateImpl::GetTracingProcessId() const {
- return tracing_process_id_;
-}
-
-} // namespace tracing
diff --git a/chromium/components/tracing/child/child_memory_dump_manager_delegate_impl.h b/chromium/components/tracing/child/child_memory_dump_manager_delegate_impl.h
deleted file mode 100644
index fc27d96f279..00000000000
--- a/chromium/components/tracing/child/child_memory_dump_manager_delegate_impl.h
+++ /dev/null
@@ -1,85 +0,0 @@
-// Copyright 2015 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 COMPONENTS_TRACING_CHILD_CHILD_MEMORY_DUMP_MANAGER_DELEGATE_IMPL_H_
-#define COMPONENTS_TRACING_CHILD_CHILD_MEMORY_DUMP_MANAGER_DELEGATE_IMPL_H_
-
-#include "base/trace_event/memory_dump_manager.h"
-
-#include <stdint.h>
-
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/singleton.h"
-#include "base/synchronization/lock.h"
-#include "components/tracing/tracing_export.h"
-
-namespace base {
-class SingleThreadTaskRunner;
-} // namespace base
-
-namespace tracing {
-
-class ChildTraceMessageFilter;
-
-// This class is a simple proxy class between the MemoryDumpManager and the
-// ChildTraceMessageFilter. It's only purpose is to adapt the lifetime of
-// CTMF to the demands of MDM, which expects the delegate to be thread-safe
-// and long lived. CTMF, instead, can be torn down during browser shutdown.
-// This class is registered as MDM delegate in child processes and handles
-// gracefully (and thread-safely) failures in the case of a lack of the CTMF.
-class TRACING_EXPORT ChildMemoryDumpManagerDelegateImpl
- : public base::trace_event::MemoryDumpManagerDelegate {
- public:
- static ChildMemoryDumpManagerDelegateImpl* GetInstance();
-
- // base::trace_event::MemoryDumpManagerDelegate implementation.
- void RequestGlobalMemoryDump(
- const base::trace_event::MemoryDumpRequestArgs& args,
- const base::trace_event::MemoryDumpCallback& callback) override;
- uint64_t GetTracingProcessId() const override;
-
- void SetChildTraceMessageFilter(ChildTraceMessageFilter* ctmf);
-
- // Pass kInvalidTracingProcessId to invalidate the id.
- void set_tracing_process_id(uint64_t id) {
- DCHECK(tracing_process_id_ ==
- base::trace_event::MemoryDumpManager::kInvalidTracingProcessId ||
- id ==
- base::trace_event::MemoryDumpManager::kInvalidTracingProcessId ||
- id == tracing_process_id_);
- tracing_process_id_ = id;
- }
-
- protected:
- // Make CreateProcessDump() visible to ChildTraceMessageFilter.
- friend class ChildTraceMessageFilter;
-
- private:
- friend struct base::DefaultSingletonTraits<
- ChildMemoryDumpManagerDelegateImpl>;
-
- ChildMemoryDumpManagerDelegateImpl();
- ~ChildMemoryDumpManagerDelegateImpl() override;
-
- ChildTraceMessageFilter* ctmf_; // Not owned.
-
- // The SingleThreadTaskRunner where the |ctmf_| lives.
- // It is NULL iff |cmtf_| is NULL.
- scoped_refptr<base::SingleThreadTaskRunner> ctmf_task_runner_;
-
- // Protects from concurrent access to |ctmf_task_runner_| to allow
- // RequestGlobalMemoryDump to be called from arbitrary threads.
- base::Lock lock_;
-
- // The unique id of the child process, created for tracing and is expected to
- // be valid only when tracing is enabled.
- uint64_t tracing_process_id_;
-
- DISALLOW_COPY_AND_ASSIGN(ChildMemoryDumpManagerDelegateImpl);
-};
-
-} // namespace tracing
-
-#endif // COMPONENTS_TRACING_CHILD_CHILD_MEMORY_DUMP_MANAGER_DELEGATE_IMPL_H_
diff --git a/chromium/components/tracing/child/child_trace_message_filter.cc b/chromium/components/tracing/child/child_trace_message_filter.cc
index ed2be875c7d..2cd76dc7b2a 100644
--- a/chromium/components/tracing/child/child_trace_message_filter.cc
+++ b/chromium/components/tracing/child/child_trace_message_filter.cc
@@ -8,11 +8,13 @@
#include "base/memory/ref_counted_memory.h"
#include "base/metrics/statistics_recorder.h"
+#include "base/trace_event/memory_dump_manager.h"
#include "base/trace_event/trace_event.h"
-#include "components/tracing/child/child_memory_dump_manager_delegate_impl.h"
+#include "components/tracing/common/process_metrics_memory_dump_provider.h"
#include "components/tracing/common/tracing_messages.h"
#include "ipc/ipc_channel.h"
+using base::trace_event::MemoryDumpManager;
using base::trace_event::TraceLog;
namespace tracing {
@@ -25,16 +27,20 @@ const int kMinTimeBetweenHistogramChangesInSeconds = 10;
ChildTraceMessageFilter::ChildTraceMessageFilter(
base::SingleThreadTaskRunner* ipc_task_runner)
- : sender_(NULL),
- ipc_task_runner_(ipc_task_runner),
- pending_memory_dump_guid_(0) {
-}
+ : enabled_tracing_modes_(0),
+ sender_(NULL),
+ ipc_task_runner_(ipc_task_runner) {}
void ChildTraceMessageFilter::OnFilterAdded(IPC::Channel* channel) {
sender_ = channel;
sender_->Send(new TracingHostMsg_ChildSupportsTracing());
- ChildMemoryDumpManagerDelegateImpl::GetInstance()->SetChildTraceMessageFilter(
- this);
+
+#if !defined(OS_LINUX) && !defined(OS_NACL)
+ // On linux the browser process takes care of dumping process metrics.
+ // The child process is not allowed to do so due to BPF sandbox.
+ tracing::ProcessMetricsMemoryDumpProvider::RegisterForProcess(
+ base::kNullProcessId);
+#endif
}
void ChildTraceMessageFilter::SetSenderForTesting(IPC::Sender* sender) {
@@ -42,8 +48,6 @@ void ChildTraceMessageFilter::SetSenderForTesting(IPC::Sender* sender) {
}
void ChildTraceMessageFilter::OnFilterRemoved() {
- ChildMemoryDumpManagerDelegateImpl::GetInstance()->SetChildTraceMessageFilter(
- nullptr);
sender_ = NULL;
}
@@ -54,10 +58,6 @@ bool ChildTraceMessageFilter::OnMessageReceived(const IPC::Message& message) {
IPC_MESSAGE_HANDLER(TracingMsg_EndTracing, OnEndTracing)
IPC_MESSAGE_HANDLER(TracingMsg_CancelTracing, OnCancelTracing)
IPC_MESSAGE_HANDLER(TracingMsg_GetTraceLogStatus, OnGetTraceLogStatus)
- IPC_MESSAGE_HANDLER(TracingMsg_ProcessMemoryDumpRequest,
- OnProcessMemoryDumpRequest)
- IPC_MESSAGE_HANDLER(TracingMsg_GlobalMemoryDumpResponse,
- OnGlobalMemoryDumpResponse)
IPC_MESSAGE_HANDLER(TracingMsg_SetUMACallback, OnSetUMACallback)
IPC_MESSAGE_HANDLER(TracingMsg_ClearUMACallback, OnClearUMACallback)
IPC_MESSAGE_UNHANDLED(handled = false)
@@ -78,15 +78,18 @@ void ChildTraceMessageFilter::OnBeginTracing(
base::TimeDelta time_offset = base::TimeTicks::Now() - browser_time;
TraceLog::GetInstance()->SetTimeOffset(time_offset);
#endif
- ChildMemoryDumpManagerDelegateImpl::GetInstance()->set_tracing_process_id(
- tracing_process_id);
- TraceLog::GetInstance()->SetEnabled(
- base::trace_event::TraceConfig(trace_config_str),
- base::trace_event::TraceLog::RECORDING_MODE);
+ MemoryDumpManager::GetInstance()->set_tracing_process_id(tracing_process_id);
+ const base::trace_event::TraceConfig trace_config(trace_config_str);
+ enabled_tracing_modes_ = base::trace_event::TraceLog::RECORDING_MODE;
+ if (!trace_config.event_filters().empty())
+ enabled_tracing_modes_ |= base::trace_event::TraceLog::FILTERING_MODE;
+ TraceLog::GetInstance()->SetEnabled(trace_config, enabled_tracing_modes_);
}
void ChildTraceMessageFilter::OnEndTracing() {
- TraceLog::GetInstance()->SetDisabled();
+ DCHECK(enabled_tracing_modes_);
+ TraceLog::GetInstance()->SetDisabled(enabled_tracing_modes_);
+ enabled_tracing_modes_ = 0;
// Flush will generate one or more callbacks to OnTraceDataCollected
// synchronously or asynchronously. EndTracingAck will be sent in the last
@@ -95,8 +98,8 @@ void ChildTraceMessageFilter::OnEndTracing() {
TraceLog::GetInstance()->Flush(
base::Bind(&ChildTraceMessageFilter::OnTraceDataCollected, this));
- ChildMemoryDumpManagerDelegateImpl::GetInstance()->set_tracing_process_id(
- base::trace_event::MemoryDumpManager::kInvalidTracingProcessId);
+ MemoryDumpManager::GetInstance()->set_tracing_process_id(
+ MemoryDumpManager::kInvalidTracingProcessId);
}
void ChildTraceMessageFilter::OnCancelTracing() {
@@ -129,52 +132,6 @@ void ChildTraceMessageFilter::OnTraceDataCollected(
}
}
-// Sent by the Browser's MemoryDumpManager when coordinating a global dump.
-void ChildTraceMessageFilter::OnProcessMemoryDumpRequest(
- const base::trace_event::MemoryDumpRequestArgs& args) {
- ChildMemoryDumpManagerDelegateImpl::GetInstance()->CreateProcessDump(
- args,
- base::Bind(&ChildTraceMessageFilter::OnProcessMemoryDumpDone, this));
-}
-
-void ChildTraceMessageFilter::OnProcessMemoryDumpDone(uint64_t dump_guid,
- bool success) {
- sender_->Send(
- new TracingHostMsg_ProcessMemoryDumpResponse(dump_guid, success));
-}
-
-// Initiates a dump request, asking the Browser's MemoryDumpManager to
-// coordinate a global memory dump. The Browser's MDM will answer back with a
-// MemoryDumpResponse when all the child processes (including this one) have
-// dumped, or with a NACK (|success| == false) if the dump failed (e.g., due to
-// a collision with a concurrent request from another child process).
-void ChildTraceMessageFilter::SendGlobalMemoryDumpRequest(
- const base::trace_event::MemoryDumpRequestArgs& args,
- const base::trace_event::MemoryDumpCallback& callback) {
- // If there is already another dump request pending from this child process,
- // there is no point bothering the Browser's MemoryDumpManager.
- if (pending_memory_dump_guid_) {
- if (!callback.is_null())
- callback.Run(args.dump_guid, false);
- return;
- }
-
- pending_memory_dump_guid_ = args.dump_guid;
- pending_memory_dump_callback_ = callback;
- sender_->Send(new TracingHostMsg_GlobalMemoryDumpRequest(args));
-}
-
-// Sent by the Browser's MemoryDumpManager in response of a dump request
-// initiated by this child process.
-void ChildTraceMessageFilter::OnGlobalMemoryDumpResponse(uint64_t dump_guid,
- bool success) {
- DCHECK_NE(0U, pending_memory_dump_guid_);
- pending_memory_dump_guid_ = 0;
- if (pending_memory_dump_callback_.is_null())
- return;
- pending_memory_dump_callback_.Run(dump_guid, success);
-}
-
void ChildTraceMessageFilter::OnHistogramChanged(
const std::string& histogram_name,
base::Histogram::Sample reference_lower_value,
diff --git a/chromium/components/tracing/child/child_trace_message_filter.h b/chromium/components/tracing/child/child_trace_message_filter.h
index 287abd3503d..929fa7e21cd 100644
--- a/chromium/components/tracing/child/child_trace_message_filter.h
+++ b/chromium/components/tracing/child/child_trace_message_filter.h
@@ -12,7 +12,6 @@
#include "base/memory/ref_counted_memory.h"
#include "base/metrics/histogram.h"
#include "base/time/time.h"
-#include "base/trace_event/memory_dump_request_args.h"
#include "components/tracing/tracing_export.h"
#include "ipc/message_filter.h"
@@ -33,10 +32,6 @@ class TRACING_EXPORT ChildTraceMessageFilter : public IPC::MessageFilter {
void OnFilterRemoved() override;
bool OnMessageReceived(const IPC::Message& message) override;
- void SendGlobalMemoryDumpRequest(
- const base::trace_event::MemoryDumpRequestArgs& args,
- const base::trace_event::MemoryDumpCallback& callback);
-
base::SingleThreadTaskRunner* ipc_task_runner() const {
return ipc_task_runner_;
}
@@ -58,9 +53,6 @@ class TRACING_EXPORT ChildTraceMessageFilter : public IPC::MessageFilter {
const std::string& event_name);
void OnCancelWatchEvent();
void OnWatchEventMatched();
- void OnProcessMemoryDumpRequest(
- const base::trace_event::MemoryDumpRequestArgs& args);
- void OnGlobalMemoryDumpResponse(uint64_t dump_guid, bool success);
void OnSetUMACallback(const std::string& histogram_name,
int histogram_lower_value,
int histogram_upper_value,
@@ -79,20 +71,13 @@ class TRACING_EXPORT ChildTraceMessageFilter : public IPC::MessageFilter {
const scoped_refptr<base::RefCountedString>& events_str_ptr,
bool has_more_events);
- void OnProcessMemoryDumpDone(uint64_t dump_guid, bool success);
-
void SetSenderForTesting(IPC::Sender* sender);
+ uint8_t enabled_tracing_modes_;
+
IPC::Sender* sender_;
base::SingleThreadTaskRunner* ipc_task_runner_;
- // guid of the outstanding request (to the Browser's MemoryDumpManager), if
- // any. 0 if there is no request pending.
- uint64_t pending_memory_dump_guid_;
-
- // callback of the outstanding memory dump request, if any.
- base::trace_event::MemoryDumpCallback pending_memory_dump_callback_;
-
base::Time histogram_last_changed_;
DISALLOW_COPY_AND_ASSIGN(ChildTraceMessageFilter);
diff --git a/chromium/components/tracing/child/child_trace_message_filter_browsertest.cc b/chromium/components/tracing/child/child_trace_message_filter_browsertest.cc
deleted file mode 100644
index d0d2d020a88..00000000000
--- a/chromium/components/tracing/child/child_trace_message_filter_browsertest.cc
+++ /dev/null
@@ -1,326 +0,0 @@
-// Copyright 2015 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 <stdint.h>
-
-#include <memory>
-#include <tuple>
-
-#include "base/callback.h"
-#include "base/run_loop.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "base/trace_event/memory_dump_manager.h"
-#include "base/trace_event/memory_dump_provider.h"
-#include "base/trace_event/trace_event.h"
-#include "components/tracing/child/child_memory_dump_manager_delegate_impl.h"
-#include "components/tracing/child/child_trace_message_filter.h"
-#include "components/tracing/common/tracing_messages.h"
-#include "content/public/test/render_view_test.h"
-#include "testing/gmock/include/gmock/gmock.h"
-
-using base::trace_event::MemoryDumpManager;
-using base::trace_event::MemoryDumpRequestArgs;
-using base::trace_event::MemoryDumpArgs;
-using base::trace_event::MemoryDumpLevelOfDetail;
-using base::trace_event::MemoryDumpType;
-using testing::_;
-using testing::Return;
-
-namespace tracing {
-
-// A mock dump provider, used to check that dump requests actually end up
-// creating memory dumps.
-class MockDumpProvider : public base::trace_event::MemoryDumpProvider {
- public:
- MOCK_METHOD2(OnMemoryDump,
- bool(const MemoryDumpArgs& args,
- base::trace_event::ProcessMemoryDump* pmd));
-};
-
-class ChildTracingTest : public content::RenderViewTest, public IPC::Listener {
- public:
- // Used as callback argument for MemoryDumpManager::RequestGlobalDump():
- void OnMemoryDumpCallback(uint64_t dump_guid, bool status) {
- last_callback_dump_guid_ = dump_guid;
- last_callback_status_ = status;
- ++callback_call_count_;
- }
-
- protected:
- void SetUp() override {
- // RenderViewTest::SetUp causes additional registrations, so we first
- // register the mock dump provider and ignore registrations from then on.
- // In addition to the mock dump provider, the TraceLog has already
- // registered itself by now; this cannot be prevented easily.
- mock_dump_provider_.reset(new MockDumpProvider());
- MemoryDumpManager::GetInstance()->RegisterDumpProvider(
- mock_dump_provider_.get(), "MockDumpProvider",
- base::ThreadTaskRunnerHandle::Get());
- MemoryDumpManager::GetInstance()
- ->set_dumper_registrations_ignored_for_testing(true);
-
- RenderViewTest::SetUp();
-
- callback_call_count_ = 0;
- last_callback_dump_guid_ = 0;
- last_callback_status_ = false;
- wait_for_ipc_message_type_ = 0;
- callback_ = base::Bind(&ChildTracingTest::OnMemoryDumpCallback,
- base::Unretained(this));
- task_runner_ = base::ThreadTaskRunnerHandle::Get();
- ctmf_ = make_scoped_refptr(new ChildTraceMessageFilter(task_runner_.get()));
- render_thread_->AddFilter(ctmf_.get());
-
- // Add a filter to the TestSink which allows to WaitForIPCMessage() by
- // posting a nested RunLoop closure when a given IPC Message is seen.
- render_thread_->sink().AddFilter(this);
-
- // Getting an instance of |ChildMemoryDumpManagerDelegateImpl| calls
- // |MemoryDumpManager::Initialize| with the correct delegate.
- ChildMemoryDumpManagerDelegateImpl::GetInstance();
- }
-
- void TearDown() override {
- render_thread_->sink().RemoveFilter(this);
- RenderViewTest::TearDown();
- MemoryDumpManager::GetInstance()->UnregisterDumpProvider(
- mock_dump_provider_.get());
- mock_dump_provider_.reset();
- ctmf_ = nullptr;
- task_runner_ = nullptr;
- }
-
- // IPC::Filter implementation.
- bool OnMessageReceived(const IPC::Message& message) override {
- if (message.type() == wait_for_ipc_message_type_) {
- DCHECK(!wait_for_ipc_closure_.is_null());
- task_runner_->PostTask(FROM_HERE, wait_for_ipc_closure_);
- }
- // Always propagate messages to the sink, never consume them here.
- return false;
- }
-
- const IPC::Message* WaitForIPCMessage(uint32_t message_type) {
- base::RunLoop run_loop;
- wait_for_ipc_message_type_ = message_type;
- wait_for_ipc_closure_ = run_loop.QuitClosure();
- run_loop.Run();
- wait_for_ipc_message_type_ = 0;
- wait_for_ipc_closure_.Reset();
- return render_thread_->sink().GetUniqueMessageMatching(message_type);
- }
-
- // Simulates a synthetic browser -> child (this process) IPC message.
- void SimulateSyntheticMessageFromBrowser(const IPC::Message& msg) {
- ctmf_->OnMessageReceived(msg);
- }
-
- void EnableTracingWithMemoryDumps() {
- // Re-enabling tracing could crash these tests https://crbug.com/656729 .
- if (base::trace_event::TraceLog::GetInstance()->IsEnabled()) {
- FAIL() << "Tracing seems to be already enabled. "
- "Very likely this is because the startup tracing file "
- "has been leaked from a previous test.";
- }
-
- std::string category_filter = "-*,"; // Disable all other trace categories.
- category_filter += MemoryDumpManager::kTraceCategory;
- base::trace_event::TraceConfig trace_config(category_filter, "");
- TracingMsg_BeginTracing msg(trace_config.ToString(), base::TimeTicks(), 0);
- SimulateSyntheticMessageFromBrowser(msg);
- }
-
- void DisableTracing() {
- SimulateSyntheticMessageFromBrowser(TracingMsg_EndTracing());
- }
-
- // Simulates a synthetic browser -> child process memory dump request and
- // checks that the child actually sends a response to that.
- void RequestProcessMemoryDumpAndCheckResponse(uint64_t dump_guid) {
- SimulateSyntheticMessageFromBrowser(TracingMsg_ProcessMemoryDumpRequest(
- {dump_guid, MemoryDumpType::EXPLICITLY_TRIGGERED,
- MemoryDumpLevelOfDetail::DETAILED}));
-
- // Check that a child -> browser response to the local dump request is sent.
- const IPC::Message* msg =
- WaitForIPCMessage(TracingHostMsg_ProcessMemoryDumpResponse::ID);
- EXPECT_NE(nullptr, msg);
-
- // Check that the |dump_guid| and the |success| fields are properly set.
- TracingHostMsg_ProcessMemoryDumpResponse::Param params;
- TracingHostMsg_ProcessMemoryDumpResponse::Read(msg, &params);
- const uint64_t resp_guid = std::get<0>(params);
- const bool resp_success = std::get<1>(params);
- EXPECT_EQ(dump_guid, resp_guid);
- EXPECT_TRUE(resp_success);
- }
-
- // Retrieves the MemoryDumpRequestArgs of the global memory dump request that
- // this child process tried to send to the browser. Fails if either none or
- // multiple requests were sent.
- MemoryDumpRequestArgs GetInterceptedGlobalMemoryDumpRequest() {
- const IPC::Message* msg = render_thread_->sink().GetUniqueMessageMatching(
- TracingHostMsg_GlobalMemoryDumpRequest::ID);
- EXPECT_NE(nullptr, msg);
- TracingHostMsg_GlobalMemoryDumpRequest::Param params;
- TracingHostMsg_GlobalMemoryDumpRequest::Read(msg, &params);
- MemoryDumpRequestArgs args = std::get<0>(params);
- EXPECT_NE(0U, args.dump_guid);
- return args;
- }
-
- scoped_refptr<ChildTraceMessageFilter> ctmf_;
- std::unique_ptr<MockDumpProvider> mock_dump_provider_;
- scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
- base::trace_event::MemoryDumpCallback callback_;
- uint32_t wait_for_ipc_message_type_;
- base::Closure wait_for_ipc_closure_;
- uint32_t callback_call_count_;
- uint64_t last_callback_dump_guid_;
- bool last_callback_status_;
-};
-
-// Covers the case of some browser-initiated memory dumps.
-#if defined(OS_ANDROID)
-// Flaky on Android. http://crbug.com/620734.
-#define MAYBE_BrowserInitiatedMemoryDumps DISABLED_BrowserInitiatedMemoryDumps
-#else
-#define MAYBE_BrowserInitiatedMemoryDumps BrowserInitiatedMemoryDumps
-#endif
-TEST_F(ChildTracingTest, MAYBE_BrowserInitiatedMemoryDumps) {
- const uint32_t kNumDumps = 3;
-
- EnableTracingWithMemoryDumps();
- EXPECT_CALL(*mock_dump_provider_, OnMemoryDump(_, _))
- .Times(kNumDumps)
- .WillRepeatedly(Return(true));
-
- for (uint32_t i = 0; i < kNumDumps; ++i) {
- render_thread_->sink().ClearMessages();
- RequestProcessMemoryDumpAndCheckResponse(i + 1);
- }
-
- DisableTracing();
-}
-
-// Covers the case of one simple child-initiated memory dump without callback,
-// simulating a global memory dump request to the browser (+ response).
-TEST_F(ChildTracingTest, SingleChildInitiatedMemoryDump) {
- EnableTracingWithMemoryDumps();
-
- // Expect that our mock dump provider is called when the emulated memory dump
- // request (browser -> child) is sent.
- EXPECT_CALL(*mock_dump_provider_, OnMemoryDump(_, _))
- .Times(1)
- .WillRepeatedly(Return(true));
-
- // Send the global memory dump request to the browser.
- render_thread_->sink().ClearMessages();
- MemoryDumpManager::GetInstance()->RequestGlobalDump(
- MemoryDumpType::EXPLICITLY_TRIGGERED, MemoryDumpLevelOfDetail::DETAILED);
- base::RunLoop().RunUntilIdle();
-
- // Check that the child -> browser global dump request IPC is actually sent.
- MemoryDumpRequestArgs args = GetInterceptedGlobalMemoryDumpRequest();
- EXPECT_EQ(MemoryDumpType::EXPLICITLY_TRIGGERED, args.dump_type);
-
- // Emulate a browser -> child process dump request and corresponding response.
- RequestProcessMemoryDumpAndCheckResponse(args.dump_guid);
-
- // Send a synthetic browser -> child global memory dump response.
- SimulateSyntheticMessageFromBrowser(
- TracingMsg_GlobalMemoryDumpResponse(args.dump_guid, true));
-
- DisableTracing();
-}
-
-// Covers the case of a global memory dump being requested while another one is
-// in progress and has not been acknowledged by the browser. The second request
-// is expected to fail immediately, while the first one is expected to suceed.
-TEST_F(ChildTracingTest, OverlappingChildInitiatedMemoryDumps) {
- EnableTracingWithMemoryDumps();
-
- // Expect that our mock dump provider is called only once.
- EXPECT_CALL(*mock_dump_provider_, OnMemoryDump(_, _))
- .Times(1)
- .WillRepeatedly(Return(true));
-
- // Send the global memory dump request to the browser.
- render_thread_->sink().ClearMessages();
- MemoryDumpManager::GetInstance()->RequestGlobalDump(
- MemoryDumpType::EXPLICITLY_TRIGGERED, MemoryDumpLevelOfDetail::DETAILED,
- callback_);
- base::RunLoop().RunUntilIdle();
-
- // Check that the child -> browser global dump request IPC is actually sent.
- MemoryDumpRequestArgs args = GetInterceptedGlobalMemoryDumpRequest();
- EXPECT_EQ(MemoryDumpType::EXPLICITLY_TRIGGERED, args.dump_type);
-
- // Emulate a browser -> child process dump request and corresponding response.
- RequestProcessMemoryDumpAndCheckResponse(args.dump_guid);
-
- // Before the response for the first global dump is sent, send another one,
- // and expect that to fail.
- render_thread_->sink().ClearMessages();
- MemoryDumpManager::GetInstance()->RequestGlobalDump(
- MemoryDumpType::EXPLICITLY_TRIGGERED, MemoryDumpLevelOfDetail::DETAILED,
- callback_);
- base::RunLoop().RunUntilIdle();
-
- EXPECT_EQ(1u, callback_call_count_);
- EXPECT_FALSE(last_callback_status_);
- // Whatever the guid of the second failing request is, it cannot possibly be
- // equal to the guid of the first request.
- EXPECT_NE(args.dump_guid, last_callback_dump_guid_);
-
- // Also, check that no request has been forwarded to the browser (because the
- // first request is still outstanding and has not received any response yet).
- EXPECT_EQ(nullptr, render_thread_->sink().GetUniqueMessageMatching(
- TracingHostMsg_GlobalMemoryDumpRequest::ID));
-
- // Now send a synthetic browser -> child response to the first request.
- SimulateSyntheticMessageFromBrowser(
- TracingMsg_GlobalMemoryDumpResponse(args.dump_guid, true));
-
- // Verify that the the callback for the first request is finally called.
- EXPECT_EQ(2u, callback_call_count_);
- EXPECT_EQ(args.dump_guid, last_callback_dump_guid_);
- EXPECT_TRUE(last_callback_status_);
-
- DisableTracing();
-}
-
-// Covers the case of five child-initiated global memory dumps. Each global dump
-// request has a callback, which is expected to fail for 3 out of 5 cases.
-TEST_F(ChildTracingTest, MultipleChildInitiatedMemoryDumpWithFailures) {
- const uint32_t kNumRequests = 5;
- MemoryDumpType kDumpType = MemoryDumpType::EXPLICITLY_TRIGGERED;
-
- EnableTracingWithMemoryDumps();
- EXPECT_CALL(*mock_dump_provider_, OnMemoryDump(_, _))
- .Times(kNumRequests)
- .WillRepeatedly(Return(true));
-
- for (uint32_t i = 0; i < kNumRequests; ++i) {
- render_thread_->sink().ClearMessages();
- MemoryDumpManager::GetInstance()->RequestGlobalDump(
- kDumpType, MemoryDumpLevelOfDetail::DETAILED, callback_);
- base::RunLoop().RunUntilIdle();
-
- MemoryDumpRequestArgs args = GetInterceptedGlobalMemoryDumpRequest();
- EXPECT_EQ(kDumpType, args.dump_type);
- RequestProcessMemoryDumpAndCheckResponse(args.dump_guid);
-
- const bool success = (i & 1) ? true : false;
- SimulateSyntheticMessageFromBrowser(
- TracingMsg_GlobalMemoryDumpResponse(args.dump_guid, success));
- EXPECT_EQ(i + 1, callback_call_count_);
- EXPECT_EQ(args.dump_guid, last_callback_dump_guid_);
- EXPECT_EQ(success, last_callback_status_);
- }
-
- DisableTracing();
-}
-
-} // namespace tracing
diff --git a/chromium/components/tracing/common/process_metrics_memory_dump_provider.cc b/chromium/components/tracing/common/process_metrics_memory_dump_provider.cc
index d8a29651182..2936256acd3 100644
--- a/chromium/components/tracing/common/process_metrics_memory_dump_provider.cc
+++ b/chromium/components/tracing/common/process_metrics_memory_dump_provider.cc
@@ -36,6 +36,7 @@
#include <mach/mach.h>
#include "base/numerics/safe_math.h"
+#include "base/process/process_metrics.h"
#endif // defined(OS_MACOSX)
#if defined(OS_WIN)
@@ -387,31 +388,20 @@ bool GetDyldRegions(std::vector<VMRegion>* regions) {
return true;
}
-void PopulateByteStats(VMRegion* region, const vm_region_submap_info_64& info) {
- uint32_t share_mode = info.share_mode;
- if (share_mode == SM_COW && info.ref_count == 1)
- share_mode = SM_PRIVATE;
-
- uint64_t dirty_bytes = info.pages_dirtied * PAGE_SIZE;
- uint64_t clean_bytes =
- (info.pages_resident - info.pages_reusable - info.pages_dirtied) *
- PAGE_SIZE;
- switch (share_mode) {
+void PopulateByteStats(VMRegion* region,
+ const vm_region_top_info_data_t& info) {
+ uint64_t dirty_bytes =
+ (info.private_pages_resident + info.shared_pages_resident) * PAGE_SIZE;
+ switch (info.share_mode) {
case SM_LARGE_PAGE:
case SM_PRIVATE:
- region->byte_stats_private_dirty_resident = dirty_bytes;
- region->byte_stats_private_clean_resident = clean_bytes;
- break;
case SM_COW:
region->byte_stats_private_dirty_resident = dirty_bytes;
- region->byte_stats_shared_clean_resident = clean_bytes;
- break;
case SM_SHARED:
case SM_PRIVATE_ALIASED:
case SM_TRUESHARED:
case SM_SHARED_ALIASED:
region->byte_stats_shared_dirty_resident = dirty_bytes;
- region->byte_stats_shared_clean_resident = clean_bytes;
break;
case SM_EMPTY:
break;
@@ -421,38 +411,45 @@ void PopulateByteStats(VMRegion* region, const vm_region_submap_info_64& info) {
}
}
-// Creates VMRegions from mach_vm_region_recurse. Returns whether the operation
+// Creates VMRegions using mach vm syscalls. Returns whether the operation
// succeeded.
bool GetAllRegions(std::vector<VMRegion>* regions) {
const int pid = getpid();
task_t task = mach_task_self();
mach_vm_size_t size = 0;
- vm_region_submap_info_64 info;
- natural_t depth = 1;
- mach_msg_type_number_t count = sizeof(info);
- for (mach_vm_address_t address = MACH_VM_MIN_ADDRESS;; address += size) {
- memset(&info, 0, sizeof(info));
- kern_return_t kr = mach_vm_region_recurse(
- task, &address, &size, &depth,
- reinterpret_cast<vm_region_info_t>(&info), &count);
- if (kr == KERN_INVALID_ADDRESS) // nothing else left
+ mach_vm_address_t address = MACH_VM_MIN_ADDRESS;
+ while (true) {
+ base::CheckedNumeric<mach_vm_address_t> next_address(address);
+ next_address += size;
+ if (!next_address.IsValid())
+ return false;
+ address = next_address.ValueOrDie();
+ mach_vm_address_t address_copy = address;
+
+ vm_region_top_info_data_t info;
+ base::MachVMRegionResult result =
+ base::GetTopInfo(task, &size, &address, &info);
+ if (result == base::MachVMRegionResult::Error)
+ return false;
+ if (result == base::MachVMRegionResult::Finished)
break;
- if (kr != KERN_SUCCESS) // something bad
+
+ vm_region_basic_info_64 basic_info;
+ mach_vm_size_t dummy_size = 0;
+ result = base::GetBasicInfo(task, &dummy_size, &address_copy, &basic_info);
+ if (result == base::MachVMRegionResult::Error)
return false;
- if (info.is_submap) {
- size = 0;
- ++depth;
- continue;
- }
+ if (result == base::MachVMRegionResult::Finished)
+ break;
VMRegion region;
PopulateByteStats(&region, info);
- if (info.protection & VM_PROT_READ)
+ if (basic_info.protection & VM_PROT_READ)
region.protection_flags |= VMRegion::kProtectionFlagsRead;
- if (info.protection & VM_PROT_WRITE)
+ if (basic_info.protection & VM_PROT_WRITE)
region.protection_flags |= VMRegion::kProtectionFlagsWrite;
- if (info.protection & VM_PROT_EXECUTE)
+ if (basic_info.protection & VM_PROT_EXECUTE)
region.protection_flags |= VMRegion::kProtectionFlagsExec;
char buffer[MAXPATHLEN];
@@ -460,16 +457,12 @@ bool GetAllRegions(std::vector<VMRegion>* regions) {
if (length != 0)
region.mapped_file.assign(buffer, length);
- region.byte_stats_swapped = info.pages_swapped_out * PAGE_SIZE;
+ // There's no way to get swapped or clean bytes without doing a
+ // very expensive syscalls that crawls every single page in the memory
+ // object.
region.start_address = address;
region.size_in_bytes = size;
regions->push_back(region);
-
- base::CheckedNumeric<mach_vm_address_t> numeric(address);
- numeric += size;
- if (!numeric.IsValid())
- return false;
- address = numeric.ValueOrDie();
}
return true;
}
@@ -608,9 +601,24 @@ bool ProcessMetricsMemoryDumpProvider::OnMemoryDump(
bool ProcessMetricsMemoryDumpProvider::DumpProcessTotals(
const base::trace_event::MemoryDumpArgs& args,
base::trace_event::ProcessMemoryDump* pmd) {
- const uint64_t rss_bytes = rss_bytes_for_testing
- ? rss_bytes_for_testing
- : process_metrics_->GetWorkingSetSize();
+#if defined(OS_MACOSX)
+ size_t private_bytes;
+ size_t shared_bytes;
+ size_t resident_bytes;
+ size_t locked_bytes;
+ if (!process_metrics_->GetMemoryBytes(&private_bytes, &shared_bytes,
+ &resident_bytes, &locked_bytes)) {
+ return false;
+ }
+ uint64_t rss_bytes = resident_bytes;
+ pmd->process_totals()->SetExtraFieldInBytes("private_bytes", private_bytes);
+ pmd->process_totals()->SetExtraFieldInBytes("shared_bytes", shared_bytes);
+ pmd->process_totals()->SetExtraFieldInBytes("locked_bytes", locked_bytes);
+#else
+ uint64_t rss_bytes = process_metrics_->GetWorkingSetSize();
+#endif // defined(OS_MACOSX)
+ if (rss_bytes_for_testing)
+ rss_bytes = rss_bytes_for_testing;
// rss_bytes will be 0 if the process ended while dumping.
if (!rss_bytes)
@@ -637,12 +645,6 @@ bool ProcessMetricsMemoryDumpProvider::DumpProcessTotals(
}
close(clear_refs_fd);
}
-#elif defined(MACOSX)
- size_t private_bytes;
- bool res = process_metrics_->GetMemoryBytes(&private_bytes,
- nullptr /* shared_bytes */);
- if (res)
- pmd->process_totals()->SetExtraFieldInBytes("private_bytes", private_bytes);
#elif defined(OS_WIN)
if (args.level_of_detail ==
base::trace_event::MemoryDumpLevelOfDetail::DETAILED) {
diff --git a/chromium/components/tracing/common/process_metrics_memory_dump_provider_unittest.cc b/chromium/components/tracing/common/process_metrics_memory_dump_provider_unittest.cc
index 77124349694..b28d3f2aad6 100644
--- a/chromium/components/tracing/common/process_metrics_memory_dump_provider_unittest.cc
+++ b/chromium/components/tracing/common/process_metrics_memory_dump_provider_unittest.cc
@@ -410,28 +410,5 @@ TEST(ProcessMetricsMemoryDumpProviderTest, TestMachOReading) {
EXPECT_TRUE(found_appkit);
}
-TEST(ProcessMetricsMemoryDumpProviderTest, NoDuplicateRegions) {
- using VMRegion = base::trace_event::ProcessMemoryMaps::VMRegion;
- ProcessMetricsMemoryDumpProvider mdp(base::kNullProcessId);
- base::trace_event::MemoryDumpArgs args;
- base::trace_event::ProcessMemoryDump dump(nullptr, args);
- ASSERT_TRUE(mdp.DumpProcessMemoryMaps(args, &dump));
- ASSERT_TRUE(dump.has_process_mmaps());
-
- std::vector<VMRegion> regions;
- regions.reserve(dump.process_mmaps()->vm_regions().size());
- for (const VMRegion& region : dump.process_mmaps()->vm_regions())
- regions.push_back(region);
- std::sort(regions.begin(), regions.end(),
- [](const VMRegion& a, const VMRegion& b) -> bool {
- return a.start_address < b.start_address;
- });
- uint64_t last_address = 0;
- for (const VMRegion& region : regions) {
- EXPECT_GE(region.start_address, last_address);
- last_address = region.start_address + region.size_in_bytes;
- }
-}
-
#endif // defined(OS_MACOSX)
} // namespace tracing
diff --git a/chromium/components/tracing/common/trace_startup.cc b/chromium/components/tracing/common/trace_startup.cc
index 2c8ae37025c..551564c6709 100644
--- a/chromium/components/tracing/common/trace_startup.cc
+++ b/chromium/components/tracing/common/trace_startup.cc
@@ -38,10 +38,14 @@ void EnableStartupTracingIfNeeded(bool can_access_file_system) {
trace_config, base::trace_event::TraceLog::RECORDING_MODE);
} else if (can_access_file_system &&
tracing::TraceConfigFile::GetInstance()->IsEnabled()) {
+ const base::trace_event::TraceConfig& trace_config =
+ tracing::TraceConfigFile::GetInstance()->GetTraceConfig();
+ uint8_t modes = base::trace_event::TraceLog::RECORDING_MODE;
+ if (!trace_config.event_filters().empty())
+ modes |= base::trace_event::TraceLog::FILTERING_MODE;
// This checks kTraceConfigFile switch.
base::trace_event::TraceLog::GetInstance()->SetEnabled(
- tracing::TraceConfigFile::GetInstance()->GetTraceConfig(),
- base::trace_event::TraceLog::RECORDING_MODE);
+ tracing::TraceConfigFile::GetInstance()->GetTraceConfig(), modes);
}
}
diff --git a/chromium/components/tracing/core/proto_zero_message.cc b/chromium/components/tracing/core/proto_zero_message.cc
index a555683428c..20785476d13 100644
--- a/chromium/components/tracing/core/proto_zero_message.cc
+++ b/chromium/components/tracing/core/proto_zero_message.cc
@@ -24,7 +24,7 @@ ProtoZeroMessage::ProtoZeroMessage() {
// |nested_messages_arena_| and implictly destroyed when the arena of the
// root message goes away. This is fine as long as all the fields are PODs,
// hence the static_assert below.
- static_assert(base::is_trivially_destructible<ProtoZeroMessage>::value,
+ static_assert(std::is_trivially_destructible<ProtoZeroMessage>::value,
"ProtoZeroMessage must be trivially destructible");
static_assert(
diff --git a/chromium/components/tracing/tools/proto_zero_plugin/BUILD.gn b/chromium/components/tracing/tools/proto_zero_plugin/BUILD.gn
index cdf0eb16073..15a71404391 100644
--- a/chromium/components/tracing/tools/proto_zero_plugin/BUILD.gn
+++ b/chromium/components/tracing/tools/proto_zero_plugin/BUILD.gn
@@ -12,5 +12,11 @@ if (current_toolchain == host_toolchain) {
deps = [
"//third_party/protobuf:protoc_lib",
]
+ if (is_win) {
+ # TODO(thomasanderson): remove when https://crbug.com/703251 is resolved
+ # by Microsoft.
+ configs -= [ "//build/config/win:default_incremental_linking" ]
+ configs += [ "//build/config/win:no_incremental_linking" ]
+ }
}
}