summaryrefslogtreecommitdiffstats
path: root/base/trace_event
diff options
context:
space:
mode:
authorprimiano <primiano@chromium.org>2015-02-24 09:52:32 -0800
committerCommit bot <commit-bot@chromium.org>2015-02-24 17:53:42 +0000
commit5a489957e8d98057c2ffbfb2f403b7d8cc2e45a5 (patch)
treec712df0071bd6dcac1c3859f28984080f84233c4 /base/trace_event
parent63aa2f732a03ce5f1a930179609d7a4573f289f6 (diff)
downloadchromium_src-5a489957e8d98057c2ffbfb2f403b7d8cc2e45a5.zip
chromium_src-5a489957e8d98057c2ffbfb2f403b7d8cc2e45a5.tar.gz
chromium_src-5a489957e8d98057c2ffbfb2f403b7d8cc2e45a5.tar.bz2
[tracing] memory maps dump provider skeleton
This CL introduces the skeleton (data model and dump provider stub) for snapshotting memory maps into the traces (via MemoryDumpManager). In the next CLs, the actual code to retrieve the data for the various OSs (or at least some of them) will be introduced. BUG=460884 Review URL: https://codereview.chromium.org/928723004 Cr-Commit-Position: refs/heads/master@{#317821}
Diffstat (limited to 'base/trace_event')
-rw-r--r--base/trace_event/process_memory_dump.cc8
-rw-r--r--base/trace_event/process_memory_dump.h8
-rw-r--r--base/trace_event/process_memory_maps.cc45
-rw-r--r--base/trace_event/process_memory_maps.h54
-rw-r--r--base/trace_event/process_memory_maps_dump_provider.cc67
-rw-r--r--base/trace_event/process_memory_maps_dump_provider.h42
-rw-r--r--base/trace_event/process_memory_maps_dump_provider_unittest.cc43
7 files changed, 266 insertions, 1 deletions
diff --git a/base/trace_event/process_memory_dump.cc b/base/trace_event/process_memory_dump.cc
index 6da9132..5363db55 100644
--- a/base/trace_event/process_memory_dump.cc
+++ b/base/trace_event/process_memory_dump.cc
@@ -10,7 +10,8 @@
namespace base {
namespace trace_event {
-ProcessMemoryDump::ProcessMemoryDump() : has_process_totals_(false) {
+ProcessMemoryDump::ProcessMemoryDump()
+ : has_process_totals_(false), has_process_mmaps_(false) {
}
ProcessMemoryDump::~ProcessMemoryDump() {
@@ -23,6 +24,11 @@ void ProcessMemoryDump::AsValueInto(TracedValue* value) const {
process_totals_.AsValueInto(value);
value->EndDictionary();
}
+ if (has_process_mmaps_) {
+ value->BeginDictionary("process_mmaps");
+ process_mmaps_.AsValueInto(value);
+ value->EndDictionary();
+ }
}
} // namespace trace_event
diff --git a/base/trace_event/process_memory_dump.h b/base/trace_event/process_memory_dump.h
index f70537b..4256c4c 100644
--- a/base/trace_event/process_memory_dump.h
+++ b/base/trace_event/process_memory_dump.h
@@ -6,6 +6,7 @@
#define BASE_TRACE_EVENT_PROCESS_MEMORY_DUMP_H_
#include "base/base_export.h"
+#include "base/trace_event/process_memory_maps.h"
#include "base/trace_event/process_memory_totals.h"
namespace base {
@@ -31,10 +32,17 @@ class BASE_EXPORT ProcessMemoryDump {
bool has_process_totals() const { return has_process_totals_; }
void set_has_process_totals() { has_process_totals_ = true; }
+ ProcessMemoryMaps* process_mmaps() { return &process_mmaps_; }
+ bool has_process_mmaps() const { return has_process_mmaps_; }
+ void set_has_process_mmaps() { has_process_mmaps_ = true; }
+
private:
ProcessMemoryTotals process_totals_;
bool has_process_totals_;
+ ProcessMemoryMaps process_mmaps_;
+ bool has_process_mmaps_;
+
DISALLOW_COPY_AND_ASSIGN(ProcessMemoryDump);
};
diff --git a/base/trace_event/process_memory_maps.cc b/base/trace_event/process_memory_maps.cc
new file mode 100644
index 0000000..bf3c5a0
--- /dev/null
+++ b/base/trace_event/process_memory_maps.cc
@@ -0,0 +1,45 @@
+// 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 "base/trace_event/process_memory_maps.h"
+
+#include "base/trace_event/trace_event_argument.h"
+
+namespace base {
+namespace trace_event {
+
+// static
+const uint32 ProcessMemoryMaps::VMRegion::kProtectionFlagsRead = 4;
+const uint32 ProcessMemoryMaps::VMRegion::kProtectionFlagsWrite = 2;
+const uint32 ProcessMemoryMaps::VMRegion::kProtectionFlagsExec = 1;
+
+ProcessMemoryMaps::ProcessMemoryMaps() {
+}
+
+ProcessMemoryMaps::~ProcessMemoryMaps() {
+}
+
+void ProcessMemoryMaps::AsValueInto(TracedValue* value) const {
+ value->BeginArray("vm_regions");
+ for (const auto& region : vm_regions_) {
+ value->BeginDictionary();
+
+ value->SetDouble("start_address", region.start_address);
+ value->SetDouble("size_in_bytes", region.size_in_bytes);
+ value->SetInteger("protection_flags", region.protection_flags);
+ value->SetString("mapped_file", region.mapped_file);
+ value->SetDouble("mapped_file_offset", region.mapped_file_offset);
+
+ value->BeginDictionary("byte_stats");
+ value->SetDouble("resident", region.byte_stats_resident);
+ value->SetDouble("anonymous", region.byte_stats_anonymous);
+ value->EndDictionary();
+
+ value->EndDictionary();
+ }
+ value->EndArray();
+}
+
+} // namespace trace_event
+} // namespace base
diff --git a/base/trace_event/process_memory_maps.h b/base/trace_event/process_memory_maps.h
new file mode 100644
index 0000000..70f6610
--- /dev/null
+++ b/base/trace_event/process_memory_maps.h
@@ -0,0 +1,54 @@
+// 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 BASE_TRACE_EVENT_PROCESS_MEMORY_MAPS_H_
+#define BASE_TRACE_EVENT_PROCESS_MEMORY_MAPS_H_
+
+#include <string>
+#include <vector>
+
+#include "base/base_export.h"
+#include "base/basictypes.h"
+
+namespace base {
+namespace trace_event {
+
+class TracedValue;
+
+// Data model for process-wide memory stats.
+class BASE_EXPORT ProcessMemoryMaps {
+ public:
+ struct VMRegion {
+ static const uint32 kProtectionFlagsRead;
+ static const uint32 kProtectionFlagsWrite;
+ static const uint32 kProtectionFlagsExec;
+
+ uint64 start_address;
+ uint64 size_in_bytes;
+ uint32 protection_flags;
+ std::string mapped_file;
+ uint64 mapped_file_offset;
+ uint64 byte_stats_resident;
+ uint64 byte_stats_anonymous;
+ };
+
+ ProcessMemoryMaps();
+ ~ProcessMemoryMaps();
+
+ void AddVMRegion(const VMRegion& region) { vm_regions_.push_back(region); }
+ const std::vector<VMRegion>& vm_regions() const { return vm_regions_; }
+
+ // Called at trace generation time to populate the TracedValue.
+ void AsValueInto(TracedValue* value) const;
+
+ private:
+ std::vector<VMRegion> vm_regions_;
+
+ DISALLOW_COPY_AND_ASSIGN(ProcessMemoryMaps);
+};
+
+} // namespace trace_event
+} // namespace base
+
+#endif // BASE_TRACE_EVENT_PROCESS_MEMORY_MAPS_H_
diff --git a/base/trace_event/process_memory_maps_dump_provider.cc b/base/trace_event/process_memory_maps_dump_provider.cc
new file mode 100644
index 0000000..b6fba80
--- /dev/null
+++ b/base/trace_event/process_memory_maps_dump_provider.cc
@@ -0,0 +1,67 @@
+// 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 "base/trace_event/process_memory_maps_dump_provider.h"
+
+#include <fstream>
+
+#include "base/logging.h"
+#include "base/process/process_metrics.h"
+#include "base/trace_event/process_memory_dump.h"
+#include "base/trace_event/process_memory_maps.h"
+
+namespace base {
+namespace trace_event {
+
+#if defined(OS_LINUX) || defined(OS_ANDROID)
+// static
+std::istream* ProcessMemoryMapsDumpProvider::proc_smaps_for_testing = nullptr;
+
+namespace {
+uint32 ReadLinuxProcSmapsFile(std::istream* smaps, ProcessMemoryMaps* pmm) {
+ if (!smaps->good()) {
+ LOG(ERROR) << "Could not read smaps file.";
+ return 0;
+ }
+ uint32 num_regions_processed = 0;
+ // TODO(primiano): in next CLs add the actual code to process the smaps file.
+ return num_regions_processed;
+}
+} // namespace
+#endif // defined(OS_LINUX) || defined(OS_ANDROID)
+
+// static
+ProcessMemoryMapsDumpProvider* ProcessMemoryMapsDumpProvider::GetInstance() {
+ return Singleton<ProcessMemoryMapsDumpProvider,
+ LeakySingletonTraits<ProcessMemoryMapsDumpProvider>>::get();
+}
+
+ProcessMemoryMapsDumpProvider::ProcessMemoryMapsDumpProvider() {
+}
+
+ProcessMemoryMapsDumpProvider::~ProcessMemoryMapsDumpProvider() {
+}
+
+// Called at trace dump point time. Creates a snapshot the memory maps for the
+// current process.
+void ProcessMemoryMapsDumpProvider::DumpInto(ProcessMemoryDump* pmd) {
+ uint32 res = 0;
+
+#if defined(OS_LINUX) || defined(OS_ANDROID)
+ if (UNLIKELY(proc_smaps_for_testing)) {
+ res = ReadLinuxProcSmapsFile(proc_smaps_for_testing, pmd->process_mmaps());
+ } else {
+ std::ifstream proc_self_smaps("/proc/self/smaps");
+ res = ReadLinuxProcSmapsFile(&proc_self_smaps, pmd->process_mmaps());
+ }
+#else
+ LOG(ERROR) << "ProcessMemoryMaps dump provider is supported only on Linux";
+#endif
+
+ if (res > 0)
+ pmd->set_has_process_mmaps();
+}
+
+} // namespace trace_event
+} // namespace base
diff --git a/base/trace_event/process_memory_maps_dump_provider.h b/base/trace_event/process_memory_maps_dump_provider.h
new file mode 100644
index 0000000..543f7fd
--- /dev/null
+++ b/base/trace_event/process_memory_maps_dump_provider.h
@@ -0,0 +1,42 @@
+// 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 BASE_TRACE_EVENT_PROCESS_MEMORY_MAPS_DUMP_PROVIDER_H_
+#define BASE_TRACE_EVENT_PROCESS_MEMORY_MAPS_DUMP_PROVIDER_H_
+
+#include <istream>
+
+#include "base/gtest_prod_util.h"
+#include "base/memory/singleton.h"
+#include "base/trace_event/memory_dump_provider.h"
+
+namespace base {
+namespace trace_event {
+
+// Dump provider which collects process-wide memory stats.
+class BASE_EXPORT ProcessMemoryMapsDumpProvider : public MemoryDumpProvider {
+ public:
+ static ProcessMemoryMapsDumpProvider* GetInstance();
+
+ // MemoryDumpProvider implementation.
+ void DumpInto(ProcessMemoryDump* pmd) override;
+
+ private:
+ friend struct DefaultSingletonTraits<ProcessMemoryMapsDumpProvider>;
+ FRIEND_TEST_ALL_PREFIXES(ProcessMemoryMapsDumpProviderTest, ParseProcSmaps);
+
+#if defined(OS_LINUX) || defined(OS_ANDROID)
+ static std::istream* proc_smaps_for_testing;
+#endif
+
+ ProcessMemoryMapsDumpProvider();
+ ~ProcessMemoryMapsDumpProvider() override;
+
+ DISALLOW_COPY_AND_ASSIGN(ProcessMemoryMapsDumpProvider);
+};
+
+} // namespace trace_event
+} // namespace base
+
+#endif // BASE_TRACE_EVENT_PROCESS_MEMORY_MAPS_DUMP_PROVIDER_H_
diff --git a/base/trace_event/process_memory_maps_dump_provider_unittest.cc b/base/trace_event/process_memory_maps_dump_provider_unittest.cc
new file mode 100644
index 0000000..33c1bbb
--- /dev/null
+++ b/base/trace_event/process_memory_maps_dump_provider_unittest.cc
@@ -0,0 +1,43 @@
+// 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 "base/trace_event/process_memory_maps_dump_provider.h"
+
+#include <fstream>
+#include <sstream>
+
+#include "base/trace_event/process_memory_dump.h"
+#include "base/trace_event/process_memory_maps.h"
+#include "base/trace_event/trace_event_argument.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace base {
+namespace trace_event {
+
+#if defined(OS_LINUX) || defined(OS_ANDROID)
+TEST(ProcessMemoryMapsDumpProviderTest, ParseProcSmaps) {
+ auto pmmdp = ProcessMemoryMapsDumpProvider::GetInstance();
+
+ // Emulate a non-existent /proc/self/smaps.
+ ProcessMemoryDump pmd_invalid;
+ std::ifstream non_existent_file("/tmp/does-not-exist");
+ ProcessMemoryMapsDumpProvider::proc_smaps_for_testing = &non_existent_file;
+ CHECK_EQ(false, non_existent_file.good());
+ pmmdp->DumpInto(&pmd_invalid);
+ ASSERT_FALSE(pmd_invalid.has_process_mmaps());
+
+ // Emulate an empty /proc/self/smaps.
+ std::ifstream empty_file("/dev/null");
+ ProcessMemoryMapsDumpProvider::proc_smaps_for_testing = &empty_file;
+ CHECK_EQ(true, empty_file.good());
+ pmmdp->DumpInto(&pmd_invalid);
+ ASSERT_FALSE(pmd_invalid.has_process_mmaps());
+
+ // TODO(primiano): in the next CLs add the code to parse some actual smaps
+ // files and check that the parsing logic of the dump provider holds.
+}
+#endif // defined(OS_LINUX) || defined(OS_ANDROID)
+
+} // namespace trace_event
+} // namespace base