summaryrefslogtreecommitdiffstats
path: root/base/trace_event
diff options
context:
space:
mode:
authorprimiano <primiano@chromium.org>2015-03-20 08:20:31 -0700
committerCommit bot <commit-bot@chromium.org>2015-03-20 15:21:11 +0000
commit165d819227077a11933773b7d2dfd3c538b24a5e (patch)
tree3e62fde9ef16dd7b4bd4cd20959547194e9c8864 /base/trace_event
parent1345722026bb273cd577e72b93c2d62861288e07 (diff)
downloadchromium_src-165d819227077a11933773b7d2dfd3c538b24a5e.zip
chromium_src-165d819227077a11933773b7d2dfd3c538b24a5e.tar.gz
chromium_src-165d819227077a11933773b7d2dfd3c538b24a5e.tar.bz2
[tracing] Improve the memory maps dumper generation format.
This CL reworks the trace generation format for the memory maps dumper according to latest discussion in the design doc "Memory Dumping: Mmap and Smap data dumping details" (http://goo.gl/e6WRnQ). Furthermore this CL changes the output format of the total dumper to dump a hex string rather than a float, in order to be consistent with the mmaps dumper. See http://pastebin.com/EHdNDMXN for an example of the generated JSON. BUG=460884 Review URL: https://codereview.chromium.org/947103003 Cr-Commit-Position: refs/heads/master@{#321570}
Diffstat (limited to 'base/trace_event')
-rw-r--r--base/trace_event/process_memory_maps.cc26
-rw-r--r--base/trace_event/process_memory_maps.h10
-rw-r--r--base/trace_event/process_memory_maps_dump_provider.cc28
-rw-r--r--base/trace_event/process_memory_maps_dump_provider_unittest.cc30
-rw-r--r--base/trace_event/process_memory_totals.cc5
-rw-r--r--base/trace_event/process_memory_totals.h2
-rw-r--r--base/trace_event/process_memory_totals_dump_provider_unittest.cc6
7 files changed, 66 insertions, 41 deletions
diff --git a/base/trace_event/process_memory_maps.cc b/base/trace_event/process_memory_maps.cc
index bf3c5a0..d553ee8 100644
--- a/base/trace_event/process_memory_maps.cc
+++ b/base/trace_event/process_memory_maps.cc
@@ -4,6 +4,8 @@
#include "base/trace_event/process_memory_maps.h"
+#include "base/format_macros.h"
+#include "base/strings/stringprintf.h"
#include "base/trace_event/trace_event_argument.h"
namespace base {
@@ -21,19 +23,25 @@ ProcessMemoryMaps::~ProcessMemoryMaps() {
}
void ProcessMemoryMaps::AsValueInto(TracedValue* value) const {
+ static const char kHexFmt[] = "%" PRIx64;
+
+ // Refer to the design doc goo.gl/sxfFY8 for the semantic of these fields.
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->SetString("sa", StringPrintf(kHexFmt, region.start_address));
+ value->SetString("sz", StringPrintf(kHexFmt, region.size_in_bytes));
+ value->SetInteger("pf", region.protection_flags);
+ value->SetString("mf", region.mapped_file);
+
+ value->BeginDictionary("bs"); // byte stats
+ value->SetString(
+ "pss", StringPrintf(kHexFmt, region.byte_stats_proportional_resident));
+ value->SetString("prv",
+ StringPrintf(kHexFmt, region.byte_stats_private_resident));
+ value->SetString("shr",
+ StringPrintf(kHexFmt, region.byte_stats_shared_resident));
value->EndDictionary();
value->EndDictionary();
diff --git a/base/trace_event/process_memory_maps.h b/base/trace_event/process_memory_maps.h
index 70f6610..dc1892f 100644
--- a/base/trace_event/process_memory_maps.h
+++ b/base/trace_event/process_memory_maps.h
@@ -28,9 +28,13 @@ class BASE_EXPORT ProcessMemoryMaps {
uint64 size_in_bytes;
uint32 protection_flags;
std::string mapped_file;
- uint64 mapped_file_offset;
- uint64 byte_stats_resident;
- uint64 byte_stats_anonymous;
+
+ // private_resident + shared_resident = resident set size.
+ uint64 byte_stats_private_resident;
+ uint64 byte_stats_shared_resident;
+
+ // For multiprocess accounting.
+ uint64 byte_stats_proportional_resident;
};
ProcessMemoryMaps();
diff --git a/base/trace_event/process_memory_maps_dump_provider.cc b/base/trace_event/process_memory_maps_dump_provider.cc
index fbe0eb1..d728bd3 100644
--- a/base/trace_event/process_memory_maps_dump_provider.cc
+++ b/base/trace_event/process_memory_maps_dump_provider.cc
@@ -60,7 +60,7 @@ bool ParseSmapsHeader(std::istream* smaps,
region->protection_flags |=
ProcessMemoryMaps::VMRegion::kProtectionFlagsExec;
}
- *smaps >> std::hex >> region->mapped_file_offset;
+ *smaps >> ignored; // Ignore mapped file offset.
*smaps >> ignored; // Ignore device maj-min (fc:01 in the example above).
*smaps >> ignored; // Ignore inode number (1234 in the example above).
@@ -73,9 +73,15 @@ bool ParseSmapsHeader(std::istream* smaps,
return res;
}
+uint64 ReadCounterBytes(std::istream* smaps) {
+ uint64 counter_value = 0;
+ *smaps >> std::dec >> counter_value;
+ return counter_value * 1024;
+}
+
uint32 ParseSmapsCounter(std::istream* smaps,
ProcessMemoryMaps::VMRegion* region) {
- // e.g., "RSS: 0 Kb\n"
+ // A smaps counter lines looks as follows: "RSS: 0 Kb\n"
uint32 res = 0;
std::string counter_name;
*smaps >> counter_name;
@@ -83,13 +89,17 @@ uint32 ParseSmapsCounter(std::istream* smaps,
// TODO(primiano): "Swap" should also be accounted as resident. Check
// whether Rss isn't already counting swapped and fix below if that is
// the case.
- if (counter_name == "Rss:") {
- *smaps >> std::dec >> region->byte_stats_resident;
- region->byte_stats_resident *= 1024;
+ if (counter_name == "Pss:") {
+ region->byte_stats_proportional_resident = ReadCounterBytes(smaps);
+ res = 1;
+ } else if (counter_name == "Private_Dirty:" ||
+ counter_name == "Private_Clean:") {
+ // For Private and Shared counters keep the sum of the dirty + clean stats.
+ region->byte_stats_private_resident += ReadCounterBytes(smaps);
res = 1;
- } else if (counter_name == "Anonymous:") {
- *smaps >> std::dec >> region->byte_stats_anonymous;
- region->byte_stats_anonymous *= 1024;
+ } else if (counter_name == "Shared_Dirty:" ||
+ counter_name == "Shared_Clean:") {
+ region->byte_stats_shared_resident += ReadCounterBytes(smaps);
res = 1;
}
@@ -111,7 +121,7 @@ uint32 ReadLinuxProcSmapsFile(std::istream* smaps, ProcessMemoryMaps* pmm) {
if (!smaps->good())
return 0;
- const uint32 kNumExpectedCountersPerRegion = 2;
+ const uint32 kNumExpectedCountersPerRegion = 5;
uint32 counters_parsed_for_current_region = 0;
uint32 num_valid_regions = 0;
ProcessMemoryMaps::VMRegion region;
diff --git a/base/trace_event/process_memory_maps_dump_provider_unittest.cc b/base/trace_event/process_memory_maps_dump_provider_unittest.cc
index 02fd136..0bf81ac 100644
--- a/base/trace_event/process_memory_maps_dump_provider_unittest.cc
+++ b/base/trace_event/process_memory_maps_dump_provider_unittest.cc
@@ -36,12 +36,12 @@ const char kTestSmaps1[] =
"VmFlags: rd ex mr mw me dw sd\n"
"ff000000-ff800000 -w-p 00001080 fc:01 0 /file/name with space\n"
"Size: 0 kB\n"
- "Rss: 128 kB\n"
+ "Rss: 192 kB\n"
"Pss: 128 kB\n"
- "Shared_Clean: 124 kB\n"
- "Shared_Dirty: 0 kB\n"
- "Private_Clean: 68 kB\n"
- "Private_Dirty: 0 kB\n"
+ "Shared_Clean: 120 kB\n"
+ "Shared_Dirty: 4 kB\n"
+ "Private_Clean: 60 kB\n"
+ "Private_Dirty: 8 kB\n"
"Referenced: 296 kB\n"
"Anonymous: 0 kB\n"
"AnonHugePages: 0 kB\n"
@@ -91,7 +91,7 @@ const char kTestSmaps2[] =
"7fe7ce79c000-7fe7ce7a8000 ---p 00000000 00:00 0 \n"
"Size: 48 kB\n"
"Rss: 40 kB\n"
- "Pss: 0 kB\n"
+ "Pss: 32 kB\n"
"Shared_Clean: 16 kB\n"
"Shared_Dirty: 12 kB\n"
"Private_Clean: 8 kB\n"
@@ -141,17 +141,17 @@ TEST(ProcessMemoryMapsDumpProviderTest, ParseProcSmaps) {
EXPECT_EQ(0x004be000UL - 0x00400000UL, regions_1[0].size_in_bytes);
EXPECT_EQ(kProtR | kProtX, regions_1[0].protection_flags);
EXPECT_EQ("/file/1", regions_1[0].mapped_file);
- EXPECT_EQ(0UL, regions_1[0].mapped_file_offset);
- EXPECT_EQ(296 * 1024UL, regions_1[0].byte_stats_resident);
- EXPECT_EQ(68 * 1024UL, regions_1[0].byte_stats_anonymous);
+ EXPECT_EQ(162 * 1024UL, regions_1[0].byte_stats_proportional_resident);
+ EXPECT_EQ((228 + 0) * 1024UL, regions_1[0].byte_stats_shared_resident);
+ EXPECT_EQ((0 + 68) * 1024UL, regions_1[0].byte_stats_private_resident);
EXPECT_EQ(0xff000000UL, regions_1[1].start_address);
EXPECT_EQ(0xff800000UL - 0xff000000UL, regions_1[1].size_in_bytes);
EXPECT_EQ(kProtW, regions_1[1].protection_flags);
EXPECT_EQ("/file/name with space", regions_1[1].mapped_file);
- EXPECT_EQ(0x00001080UL, regions_1[1].mapped_file_offset);
- EXPECT_EQ(128 * 1024UL, regions_1[1].byte_stats_resident);
- EXPECT_EQ(0UL, regions_1[1].byte_stats_anonymous);
+ EXPECT_EQ(128 * 1024UL, regions_1[1].byte_stats_proportional_resident);
+ EXPECT_EQ((120 + 4) * 1024UL, regions_1[1].byte_stats_shared_resident);
+ EXPECT_EQ((60 + 8) * 1024UL, regions_1[1].byte_stats_private_resident);
// Parse the 2nd smaps file.
ProcessMemoryDump pmd_2;
@@ -165,9 +165,9 @@ TEST(ProcessMemoryMapsDumpProviderTest, ParseProcSmaps) {
EXPECT_EQ(0x7fe7ce7a8000UL - 0x7fe7ce79c000UL, regions_2[0].size_in_bytes);
EXPECT_EQ(0U, regions_2[0].protection_flags);
EXPECT_EQ("", regions_2[0].mapped_file);
- EXPECT_EQ(0UL, regions_2[0].mapped_file_offset);
- EXPECT_EQ(40 * 1024UL, regions_2[0].byte_stats_resident);
- EXPECT_EQ(16 * 1024UL, regions_2[0].byte_stats_anonymous);
+ EXPECT_EQ(32 * 1024UL, regions_2[0].byte_stats_proportional_resident);
+ EXPECT_EQ((16 + 12) * 1024UL, regions_2[0].byte_stats_shared_resident);
+ EXPECT_EQ((8 + 4) * 1024UL, regions_2[0].byte_stats_private_resident);
}
#endif // defined(OS_LINUX) || defined(OS_ANDROID)
diff --git a/base/trace_event/process_memory_totals.cc b/base/trace_event/process_memory_totals.cc
index 41ad788..9b0c377 100644
--- a/base/trace_event/process_memory_totals.cc
+++ b/base/trace_event/process_memory_totals.cc
@@ -4,13 +4,16 @@
#include "base/trace_event/process_memory_totals.h"
+#include "base/format_macros.h"
+#include "base/strings/stringprintf.h"
#include "base/trace_event/trace_event_argument.h"
namespace base {
namespace trace_event {
void ProcessMemoryTotals::AsValueInto(TracedValue* value) const {
- value->SetDouble("resident_set_bytes", resident_set_bytes_);
+ value->SetString("resident_set_bytes",
+ StringPrintf("%" PRIx64, resident_set_bytes_));
}
} // namespace trace_event
diff --git a/base/trace_event/process_memory_totals.h b/base/trace_event/process_memory_totals.h
index ef0289e..29c94c9 100644
--- a/base/trace_event/process_memory_totals.h
+++ b/base/trace_event/process_memory_totals.h
@@ -13,7 +13,7 @@ namespace trace_event {
class TracedValue;
-// Dump provider which collects process-wide memory stats.
+// Data model for process-wide memory stats.
class BASE_EXPORT ProcessMemoryTotals {
public:
ProcessMemoryTotals() : resident_set_bytes_(0) {}
diff --git a/base/trace_event/process_memory_totals_dump_provider_unittest.cc b/base/trace_event/process_memory_totals_dump_provider_unittest.cc
index c37e612..372db63 100644
--- a/base/trace_event/process_memory_totals_dump_provider_unittest.cc
+++ b/base/trace_event/process_memory_totals_dump_provider_unittest.cc
@@ -12,18 +12,18 @@ namespace base {
namespace trace_event {
TEST(ProcessMemoryTotalsDumpProviderTest, DumpRSS) {
- auto mdptp = ProcessMemoryTotalsDumpProvider::GetInstance();
+ auto pmtdp = ProcessMemoryTotalsDumpProvider::GetInstance();
scoped_ptr<ProcessMemoryDump> pmd_before(new ProcessMemoryDump());
scoped_ptr<ProcessMemoryDump> pmd_after(new ProcessMemoryDump());
ProcessMemoryTotalsDumpProvider::rss_bytes_for_testing = 1024;
- mdptp->DumpInto(pmd_before.get());
+ pmtdp->DumpInto(pmd_before.get());
// Pretend that the RSS of the process increased of +1M.
const size_t kAllocSize = 1048576;
ProcessMemoryTotalsDumpProvider::rss_bytes_for_testing += kAllocSize;
- mdptp->DumpInto(pmd_after.get());
+ pmtdp->DumpInto(pmd_after.get());
ProcessMemoryTotalsDumpProvider::rss_bytes_for_testing = 0;