Commit 09b8b3a2 authored by hjd's avatar hjd Committed by Commit bot

memory-infra: Add SUMMARY_ONLY MemoryDumpType

Add a new MemoryDumpType: SUMMARY_ONLY which allows RequestGlobalDump
callers to specify the dump should not be added to the trace.

BUG=703184

Review-Url: https://codereview.chromium.org/2838913002
Cr-Commit-Position: refs/heads/master@{#467327}
parent 02ebdb39
......@@ -743,10 +743,15 @@ void MemoryDumpManager::FinalizeDumpAndAddToTrace(
ProcessId pid = kv.first; // kNullProcessId for the current process.
ProcessMemoryDump* process_memory_dump = kv.second.get();
bool added_to_trace = tracing_observer_->AddDumpToTraceIfEnabled(
&pmd_async_state->req_args, pid, process_memory_dump);
dump_successful = dump_successful && added_to_trace;
// SUMMARY_ONLY dumps are just return the summarized result in the
// ProcessMemoryDumpCallback. These shouldn't be added to the trace to
// avoid confusing trace consumers.
if (pmd_async_state->req_args.dump_type != MemoryDumpType::SUMMARY_ONLY) {
bool added_to_trace = tracing_observer_->AddDumpToTraceIfEnabled(
&pmd_async_state->req_args, pid, process_memory_dump);
dump_successful = dump_successful && added_to_trace;
}
// TODO(hjd): Transitional until we send the full PMD. See crbug.com/704203
// Don't try to fill the struct in detailed mode since it is hard to avoid
......
......@@ -221,6 +221,23 @@ class TestSequencedTaskRunner : public SequencedTaskRunner {
unsigned num_of_post_tasks_;
};
std::unique_ptr<trace_analyzer::TraceAnalyzer> GetDeserializedTrace() {
// Flush the trace into JSON.
trace_event::TraceResultBuffer buffer;
TraceResultBuffer::SimpleOutput trace_output;
buffer.SetOutputCallback(trace_output.GetCallback());
RunLoop run_loop;
buffer.Start();
trace_event::TraceLog::GetInstance()->Flush(
Bind(&OnTraceDataCollected, run_loop.QuitClosure(), Unretained(&buffer)));
run_loop.Run();
buffer.Finish();
// Analyze the JSON.
return WrapUnique(
trace_analyzer::TraceAnalyzer::Create(trace_output.json_output));
}
} // namespace
class MemoryDumpManagerTest : public testing::Test {
......@@ -1080,20 +1097,8 @@ TEST_F(MemoryDumpManagerTest, DumpOnBehalfOfOtherProcess) {
MemoryDumpLevelOfDetail::DETAILED);
DisableTracing();
// Flush the trace into JSON.
trace_event::TraceResultBuffer buffer;
TraceResultBuffer::SimpleOutput trace_output;
buffer.SetOutputCallback(trace_output.GetCallback());
RunLoop run_loop;
buffer.Start();
trace_event::TraceLog::GetInstance()->Flush(
Bind(&OnTraceDataCollected, run_loop.QuitClosure(), Unretained(&buffer)));
run_loop.Run();
buffer.Finish();
// Analyze the JSON.
std::unique_ptr<trace_analyzer::TraceAnalyzer> analyzer = WrapUnique(
trace_analyzer::TraceAnalyzer::Create(trace_output.json_output));
std::unique_ptr<trace_analyzer::TraceAnalyzer> analyzer =
GetDeserializedTrace();
trace_analyzer::TraceEventVector events;
analyzer->FindEvents(Query::EventPhaseIs(TRACE_EVENT_PHASE_MEMORY_DUMP),
&events);
......@@ -1107,6 +1112,37 @@ TEST_F(MemoryDumpManagerTest, DumpOnBehalfOfOtherProcess) {
ASSERT_EQ(events[0]->id, events[2]->id);
}
TEST_F(MemoryDumpManagerTest, SummaryOnlyDumpsArentAddedToTrace) {
using trace_analyzer::Query;
InitializeMemoryDumpManager(false /* is_coordinator */);
SetDumpProviderWhitelistForTesting(kTestMDPWhitelist);
// Standard provider with default options (create dump for current process).
MockMemoryDumpProvider mdp;
RegisterDumpProvider(&mdp, nullptr, kDefaultOptions, kWhitelistedMDPName);
EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory);
EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _)).Times(2);
EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(2).WillRepeatedly(Return(true));
RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
MemoryDumpLevelOfDetail::BACKGROUND);
RequestGlobalDumpAndWait(MemoryDumpType::SUMMARY_ONLY,
MemoryDumpLevelOfDetail::BACKGROUND);
DisableTracing();
std::unique_ptr<trace_analyzer::TraceAnalyzer> analyzer =
GetDeserializedTrace();
trace_analyzer::TraceEventVector events;
analyzer->FindEvents(Query::EventPhaseIs(TRACE_EVENT_PHASE_MEMORY_DUMP),
&events);
ASSERT_EQ(1u, events.size());
ASSERT_TRUE(trace_analyzer::CountMatches(
events, Query::EventNameIs(MemoryDumpTypeToString(
MemoryDumpType::EXPLICITLY_TRIGGERED))));
}
// Tests the basics of the UnregisterAndDeleteDumpProviderSoon(): the
// unregistration should actually delete the providers and not leak them.
TEST_F(MemoryDumpManagerTest, UnregisterAndDeleteDumpProviderSoon) {
......
......@@ -18,6 +18,8 @@ const char* MemoryDumpTypeToString(const MemoryDumpType& dump_type) {
return "explicitly_triggered";
case MemoryDumpType::PEAK_MEMORY_USAGE:
return "peak_memory_usage";
case MemoryDumpType::SUMMARY_ONLY:
return "summary_only";
}
NOTREACHED();
return "unknown";
......@@ -30,6 +32,8 @@ MemoryDumpType StringToMemoryDumpType(const std::string& str) {
return MemoryDumpType::EXPLICITLY_TRIGGERED;
if (str == "peak_memory_usage")
return MemoryDumpType::PEAK_MEMORY_USAGE;
if (str == "summary_only")
return MemoryDumpType::SUMMARY_ONLY;
NOTREACHED();
return MemoryDumpType::LAST;
}
......
......@@ -28,7 +28,8 @@ enum class MemoryDumpType {
PERIODIC_INTERVAL, // Dumping memory at periodic intervals.
EXPLICITLY_TRIGGERED, // Non maskable dump request.
PEAK_MEMORY_USAGE, // Dumping memory at detected peak total memory usage.
LAST = PEAK_MEMORY_USAGE // For IPC macros.
SUMMARY_ONLY, // Calculate just the summary & don't add to the trace.
LAST = SUMMARY_ONLY
};
// Tells the MemoryDumpProvider(s) how much detailed their dumps should be.
......
......@@ -72,6 +72,8 @@ bool MemoryTracingObserver::AddDumpToTraceIfEnabled(
if (!IsMemoryInfraTracingEnabled())
return false;
CHECK_NE(MemoryDumpType::SUMMARY_ONLY, req_args->dump_type);
const uint64_t dump_guid = req_args->dump_guid;
std::unique_ptr<TracedValue> traced_value(new TracedValue);
......
......@@ -22,6 +22,8 @@ EnumTraits<memory_instrumentation::mojom::DumpType,
return memory_instrumentation::mojom::DumpType::EXPLICITLY_TRIGGERED;
case base::trace_event::MemoryDumpType::PEAK_MEMORY_USAGE:
return memory_instrumentation::mojom::DumpType::PEAK_MEMORY_USAGE;
case base::trace_event::MemoryDumpType::SUMMARY_ONLY:
return memory_instrumentation::mojom::DumpType::SUMMARY_ONLY;
default:
CHECK(false) << "Invalid type: " << static_cast<uint8_t>(type);
// This should not be reached. Just return a random value.
......@@ -44,6 +46,9 @@ bool EnumTraits<memory_instrumentation::mojom::DumpType,
case memory_instrumentation::mojom::DumpType::PEAK_MEMORY_USAGE:
*out = base::trace_event::MemoryDumpType::PEAK_MEMORY_USAGE;
break;
case memory_instrumentation::mojom::DumpType::SUMMARY_ONLY:
*out = base::trace_event::MemoryDumpType::SUMMARY_ONLY;
break;
default:
NOTREACHED() << "Invalid type: " << static_cast<uint8_t>(input);
return false;
......
......@@ -9,7 +9,8 @@ import "mojo/common/process_id.mojom";
enum DumpType {
PERIODIC_INTERVAL,
EXPLICITLY_TRIGGERED,
PEAK_MEMORY_USAGE
PEAK_MEMORY_USAGE,
SUMMARY_ONLY
};
enum LevelOfDetail {
......
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