Commit 4a7ba126 authored by primiano's avatar primiano Committed by Commit bot

[tracing] Enable actual generation of memory dump points.

This CL introduces a new TRACE_EVENT_PHASE for memory dump
and enables the MemoryDumpManager to generate actual trace
events when CreateLocalDumpPoint is invoked.

BUG=458295

Review URL: https://codereview.chromium.org/956413002

Cr-Commit-Position: refs/heads/master@{#318727}
parent 2f52d5e1
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include <algorithm> #include <algorithm>
#include "base/atomic_sequence_num.h"
#include "base/compiler_specific.h" #include "base/compiler_specific.h"
#include "base/trace_event/memory_dump_provider.h" #include "base/trace_event/memory_dump_provider.h"
#include "base/trace_event/process_memory_dump.h" #include "base/trace_event/process_memory_dump.h"
...@@ -15,7 +16,27 @@ namespace base { ...@@ -15,7 +16,27 @@ namespace base {
namespace trace_event { namespace trace_event {
namespace { namespace {
MemoryDumpManager* g_instance_for_testing = nullptr; MemoryDumpManager* g_instance_for_testing = nullptr;
const int kTraceEventNumArgs = 1;
const char* kTraceEventArgNames[] = {"dumps"};
const unsigned char kTraceEventArgTypes[] = {TRACE_VALUE_TYPE_CONVERTABLE};
StaticAtomicSequenceNumber g_next_guid;
const char* DumpPointTypeToString(const DumpPointType& dump_point_type) {
switch (dump_point_type) {
case DumpPointType::TASK_BEGIN:
return "TASK_BEGIN";
case DumpPointType::TASK_END:
return "TASK_END";
case DumpPointType::PERIODIC_INTERVAL:
return "PERIODIC_INTERVAL";
case DumpPointType::EXPLICITLY_TRIGGERED:
return "EXPLICITLY_TRIGGERED";
}
NOTREACHED();
return "UNKNOWN";
}
} }
// TODO(primiano): this should be smarter and should do something similar to // TODO(primiano): this should be smarter and should do something similar to
...@@ -76,13 +97,18 @@ void MemoryDumpManager::UnregisterDumpProvider(MemoryDumpProvider* mdp) { ...@@ -76,13 +97,18 @@ void MemoryDumpManager::UnregisterDumpProvider(MemoryDumpProvider* mdp) {
dump_providers_enabled_.erase(it); dump_providers_enabled_.erase(it);
} }
void MemoryDumpManager::RequestDumpPoint(DumpPointType type) { void MemoryDumpManager::RequestDumpPoint(DumpPointType dump_point_type) {
// TODO(primiano): this will have more logic, IPC broadcast & co. // TODO(primiano): this will have more logic to coordinate dump points across
// multiple processes via IPC. See crbug.com/462930.
// Bail out immediately if tracing is not enabled at all. // Bail out immediately if tracing is not enabled at all.
if (!UNLIKELY(subtle::NoBarrier_Load(&memory_tracing_enabled_))) if (!UNLIKELY(subtle::NoBarrier_Load(&memory_tracing_enabled_)))
return; return;
CreateLocalDumpPoint(); // TODO(primiano): Make guid actually unique (cross-process) by hashing it
// with the PID. See crbug.com/462931 for details.
const uint64 guid = g_next_guid.GetNext();
CreateLocalDumpPoint(dump_point_type, guid);
} }
void MemoryDumpManager::BroadcastDumpRequest() { void MemoryDumpManager::BroadcastDumpRequest() {
...@@ -90,23 +116,28 @@ void MemoryDumpManager::BroadcastDumpRequest() { ...@@ -90,23 +116,28 @@ void MemoryDumpManager::BroadcastDumpRequest() {
} }
// Creates a dump point for the current process and appends it to the trace. // Creates a dump point for the current process and appends it to the trace.
void MemoryDumpManager::CreateLocalDumpPoint() { void MemoryDumpManager::CreateLocalDumpPoint(DumpPointType dump_point_type,
AutoLock lock(lock_); uint64 guid) {
bool did_any_provider_dump = false; bool did_any_provider_dump = false;
scoped_ptr<ProcessMemoryDump> pmd(new ProcessMemoryDump()); scoped_ptr<ProcessMemoryDump> pmd(new ProcessMemoryDump());
for (auto it = dump_providers_enabled_.begin(); // Serialize dump point generation so that memory dump providers don't have to
it != dump_providers_enabled_.end();) { // deal with thread safety.
MemoryDumpProvider* dump_provider = *it; {
if (!dump_provider->DumpInto(pmd.get())) { AutoLock lock(lock_);
LOG(ERROR) << "The memory dumper " << dump_provider->GetFriendlyName() for (auto it = dump_providers_enabled_.begin();
<< " failed, possibly due to sandboxing (crbug.com/461788), " it != dump_providers_enabled_.end();) {
"disabling it for current process. Try restarting chrome " MemoryDumpProvider* dump_provider = *it;
"with the --no-sandbox switch."; if (dump_provider->DumpInto(pmd.get())) {
it = dump_providers_enabled_.erase(it); did_any_provider_dump = true;
} else { ++it;
did_any_provider_dump = true; } else {
++it; LOG(ERROR) << "The memory dumper " << dump_provider->GetFriendlyName()
<< " failed, possibly due to sandboxing (crbug.com/461788), "
"disabling it for current process. Try restarting chrome "
"with the --no-sandbox switch.";
it = dump_providers_enabled_.erase(it);
}
} }
} }
...@@ -114,9 +145,15 @@ void MemoryDumpManager::CreateLocalDumpPoint() { ...@@ -114,9 +145,15 @@ void MemoryDumpManager::CreateLocalDumpPoint() {
if (!did_any_provider_dump) if (!did_any_provider_dump)
return; return;
scoped_refptr<TracedValue> value(new TracedValue()); scoped_refptr<ConvertableToTraceFormat> event_value(new TracedValue());
pmd->AsValueInto(value.get()); pmd->AsValueInto(static_cast<TracedValue*>(event_value.get()));
// TODO(primiano): add the dump point to the trace at this point. const char* const event_name = DumpPointTypeToString(dump_point_type);
TRACE_EVENT_API_ADD_TRACE_EVENT(
TRACE_EVENT_PHASE_MEMORY_DUMP,
TraceLog::GetCategoryGroupEnabled(kTraceCategory), event_name, guid,
kTraceEventNumArgs, kTraceEventArgNames, kTraceEventArgTypes,
NULL /* arg_values */, &event_value, TRACE_EVENT_FLAG_HAS_ID);
} }
void MemoryDumpManager::OnTraceLogEnabled() { void MemoryDumpManager::OnTraceLogEnabled() {
......
...@@ -43,7 +43,7 @@ class BASE_EXPORT MemoryDumpManager : public TraceLog::EnabledStateObserver { ...@@ -43,7 +43,7 @@ class BASE_EXPORT MemoryDumpManager : public TraceLog::EnabledStateObserver {
// Requests a memory dump. The dump might happen or not depending on the // Requests a memory dump. The dump might happen or not depending on the
// filters and categories specified when enabling tracing. // filters and categories specified when enabling tracing.
void RequestDumpPoint(DumpPointType type); void RequestDumpPoint(DumpPointType dump_point_type);
// TraceLog::EnabledStateObserver implementation. // TraceLog::EnabledStateObserver implementation.
void OnTraceLogEnabled() override; void OnTraceLogEnabled() override;
...@@ -65,7 +65,7 @@ class BASE_EXPORT MemoryDumpManager : public TraceLog::EnabledStateObserver { ...@@ -65,7 +65,7 @@ class BASE_EXPORT MemoryDumpManager : public TraceLog::EnabledStateObserver {
void BroadcastDumpRequest(); void BroadcastDumpRequest();
// Creates a dump point for the current process and appends it to the trace. // Creates a dump point for the current process and appends it to the trace.
void CreateLocalDumpPoint(); void CreateLocalDumpPoint(DumpPointType dump_point_type, uint64 guid);
std::vector<MemoryDumpProvider*> dump_providers_registered_; // Not owned. std::vector<MemoryDumpProvider*> dump_providers_registered_; // Not owned.
std::vector<MemoryDumpProvider*> dump_providers_enabled_; // Not owned. std::vector<MemoryDumpProvider*> dump_providers_enabled_; // Not owned.
......
...@@ -1039,6 +1039,7 @@ TRACE_EVENT_API_CLASS_EXPORT extern \ ...@@ -1039,6 +1039,7 @@ TRACE_EVENT_API_CLASS_EXPORT extern \
#define TRACE_EVENT_PHASE_CREATE_OBJECT ('N') #define TRACE_EVENT_PHASE_CREATE_OBJECT ('N')
#define TRACE_EVENT_PHASE_SNAPSHOT_OBJECT ('O') #define TRACE_EVENT_PHASE_SNAPSHOT_OBJECT ('O')
#define TRACE_EVENT_PHASE_DELETE_OBJECT ('D') #define TRACE_EVENT_PHASE_DELETE_OBJECT ('D')
#define TRACE_EVENT_PHASE_MEMORY_DUMP ('v')
// Flags for changing the behavior of TRACE_EVENT_API_ADD_TRACE_EVENT. // Flags for changing the behavior of TRACE_EVENT_API_ADD_TRACE_EVENT.
#define TRACE_EVENT_FLAG_NONE (static_cast<unsigned char>(0)) #define TRACE_EVENT_FLAG_NONE (static_cast<unsigned char>(0))
......
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