Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(14)

Unified Diff: tools/android/memdump/memdump.cc

Issue 19466005: Adding extended report to memdump with resident pages bit reporting. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | tools/android/memdump/memsymbols.py » ('j') | tools/android/memdump/memsymbols.py » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tools/android/memdump/memdump.cc
diff --git a/tools/android/memdump/memdump.cc b/tools/android/memdump/memdump.cc
index 21ef291f3d76d8f3b47814ade2e758f2725a3e95..8d1cdadde3e21e7370d45c94a08ebe6c4d3a7dbf 100644
--- a/tools/android/memdump/memdump.cc
+++ b/tools/android/memdump/memdump.cc
@@ -16,6 +16,7 @@
#include <utility>
#include <vector>
+#include "base/base64.h"
#include "base/basictypes.h"
#include "base/bind.h"
#include "base/bind_helpers.h"
@@ -30,6 +31,29 @@
namespace {
+class BitSet {
bulach 2013/07/22 12:59:39 I suppose the ndk has #include <bitset> ?
digit1 2013/07/22 21:03:14 That's true, but note that std::bitset<> is not a
Primiano Tucci (use gerrit) 2013/07/22 23:22:35 Yeah, unforunately STL's bitset require the size o
bulach 2013/07/23 08:10:57 ops, forgot that tiny detail :) thanks for the ref
+public:
Philippe 2013/07/22 09:20:55 Nit: there should be a leading space before 'publi
Primiano Tucci (use gerrit) 2013/07/22 23:22:35 Done.
+ BitSet() : nbits_(0), data_(0) { }
Philippe 2013/07/22 09:20:55 Nit: no space between the braces.
Philippe 2013/07/22 09:20:55 Nit: I believe the |data_| explicit initialization
Primiano Tucci (use gerrit) 2013/07/22 23:22:35 Done.
Primiano Tucci (use gerrit) 2013/07/22 23:22:35 Hmm, agree for nbits (see below), but _data was ju
+
+ void setSize(int nbits) {
Philippe 2013/07/22 09:20:55 Nit: maybe call this 'resize()' and also s/getData
digit1 2013/07/22 21:03:14 Also, you should use the Chromium style guide, whi
Primiano Tucci (use gerrit) 2013/07/22 23:22:35 Right, makes sense!
+ nbits_ = nbits;
Philippe 2013/07/22 09:20:55 Nit: do we need to store |nbits|? Can we entirely
Primiano Tucci (use gerrit) 2013/07/22 23:22:35 Yeah, that was just me being uber-paranoid. The at
+ data_.resize((nbits_+7)/8);
Philippe 2013/07/22 09:20:55 Nit: spaces around binary operators (here and on a
Primiano Tucci (use gerrit) 2013/07/22 23:22:35 Done.
+ memset(&data_[0], 0, getLength());
Philippe 2013/07/22 09:20:55 Nit: I believe you can delete this line and use th
Primiano Tucci (use gerrit) 2013/07/22 23:22:35 Oh, apparently I am the one missing the autofill o
+ }
+
+ void set(int bit) {
+ data_.at(bit/8) |= (1 << (bit % 8));
digit1 2013/07/22 21:03:14 nit: since 'bit' is signed, using 'bit & 7' is mor
Primiano Tucci (use gerrit) 2013/07/22 23:22:35 Great catch! Right. For the records: return arg
+ }
+
+ const char* getData() const { return &data_[0]; }
Philippe 2013/07/22 09:20:55 Nit: data_.data()?
Primiano Tucci (use gerrit) 2013/07/22 23:22:35 I'm afraid that is only possible in C++11.
+
+ int getLength() const { return data_.size(); }
digit1 2013/07/22 21:03:14 nit: This is very misleading because this doesn't
Primiano Tucci (use gerrit) 2013/07/22 23:22:35 At this point, let's do directly AsB64String().
+
+private:
+ int nbits_;
+ std::vector<char> data_;
+};
+
// An entry in /proc/<pid>/pagemap.
struct PageMapEntry {
uint64 page_frame_number : 55;
@@ -49,6 +73,7 @@ struct MemoryMap {
std::string flags;
uint start_address;
uint end_address;
+ uint offset;
int private_count;
int unevictable_private_count;
int other_shared_count;
@@ -57,6 +82,9 @@ struct MemoryMap {
// (only among the processes that are being analyzed).
std::vector<int> app_shared_counts;
std::vector<PageInfo> committed_pages;
+ // committed_pages_bits is a bitmap reflecting the present bit for all the
Philippe 2013/07/22 09:20:55 Nit: s/bitmap/bitset maybe.
Primiano Tucci (use gerrit) 2013/07/22 23:22:35 Done.
+ // virtual pages of the mapping.
+ BitSet committed_pages_bits;
};
struct ProcessMemory {
@@ -114,6 +142,11 @@ bool ParseMemoryMapLine(const std::string& line,
if (tokens->at(1).size() != strlen("rwxp"))
return false;
memory_map->flags.swap(tokens->at(1));
+ if (!base::HexStringToUInt64(tokens->at(2), &tmp))
+ return false;
+ memory_map->offset = static_cast<uint>(tmp);
+ memory_map->committed_pages_bits.setSize(
+ (memory_map->end_address - memory_map->start_address) / PAGE_SIZE);
const int map_name_index = 5;
if (tokens->size() >= map_name_index + 1) {
for (std::vector<std::string>::const_iterator it =
@@ -167,9 +200,11 @@ bool GetProcessMaps(pid_t pid, std::vector<MemoryMap>* process_maps) {
// provided memory map.
bool GetPagesForMemoryMap(int pagemap_fd,
const MemoryMap& memory_map,
- std::vector<PageInfo>* committed_pages) {
- for (uint addr = memory_map.start_address; addr < memory_map.end_address;
- addr += PAGE_SIZE) {
+ std::vector<PageInfo>* committed_pages,
+ BitSet* committed_pages_bits) {
+ for (uint addr = memory_map.start_address, page_index = 0;
+ addr < memory_map.end_address;
+ addr += PAGE_SIZE, ++page_index) {
DCHECK_EQ(0, addr % PAGE_SIZE);
PageMapEntry page_map_entry = {};
COMPILE_ASSERT(sizeof(PageMapEntry) == sizeof(uint64), unexpected_size);
@@ -182,6 +217,7 @@ bool GetPagesForMemoryMap(int pagemap_fd,
PageInfo page_info = {};
page_info.page_frame_number = page_map_entry.page_frame_number;
committed_pages->push_back(page_info);
+ committed_pages_bits->set(page_index);
}
}
return true;
@@ -387,6 +423,44 @@ void DumpProcessesMemoryMapsInShortFormat(
}
}
+void DumpProcessesMemoryMapsInExtendedFormat(
+ const std::vector<ProcessMemory>& processes_memory) {
+ std::string buf;
+ std::string app_shared_buf;
+ for (std::vector<ProcessMemory>::const_iterator it = processes_memory.begin();
+ it != processes_memory.end(); ++it) {
+ const ProcessMemory& process_memory = *it;
+ std::cout << "[ PID=" << process_memory.pid << "]" << '\n';
+ const std::vector<MemoryMap>& memory_maps = process_memory.memory_maps;
+ for (std::vector<MemoryMap>::const_iterator it = memory_maps.begin();
+ it != memory_maps.end(); ++it) {
+ const MemoryMap& memory_map = *it;
+ app_shared_buf.clear();
+ AppendAppSharedField(memory_map.app_shared_counts, &app_shared_buf);
+ std::string pages_bits(memory_map.committed_pages_bits.getData(),
+ memory_map.committed_pages_bits.getLength());
+ std::string encoded_page_bits;
+ base::Base64Encode(pages_bits, &encoded_page_bits);
+ base::SStringPrintf(
+ &buf,
+ "%x-%x %s %x private_unevictable=%d private=%d shared_app=%s "
+ "shared_other_unevictable=%d shared_other=%d \"%s\" [%s]\n",
+ memory_map.start_address,
+ memory_map.end_address,
+ memory_map.flags.c_str(),
+ memory_map.offset,
+ memory_map.unevictable_private_count * PAGE_SIZE,
+ memory_map.private_count * PAGE_SIZE,
+ app_shared_buf.c_str(),
+ memory_map.unevictable_other_shared_count * PAGE_SIZE,
+ memory_map.other_shared_count * PAGE_SIZE,
+ memory_map.name.c_str(),
+ encoded_page_bits.c_str());
+ std::cout << buf;
+ }
+ }
+}
+
bool CollectProcessMemoryInformation(int page_count_fd,
int page_flags_fd,
ProcessMemory* process_memory) {
@@ -404,7 +478,8 @@ bool CollectProcessMemoryInformation(int page_count_fd,
for (std::vector<MemoryMap>::iterator it = process_maps->begin();
it != process_maps->end(); ++it) {
std::vector<PageInfo>* const committed_pages = &it->committed_pages;
- GetPagesForMemoryMap(pagemap_fd, *it, committed_pages);
+ BitSet* pages_bits = &it->committed_pages_bits;
Philippe 2013/07/22 09:20:55 Nit: 'BitSet* const pages_bits' maybe for consiste
Primiano Tucci (use gerrit) 2013/07/22 23:22:35 Done.
+ GetPagesForMemoryMap(pagemap_fd, *it, committed_pages, pages_bits);
SetPagesInfo(page_count_fd, page_flags_fd, committed_pages);
}
return true;
@@ -420,17 +495,17 @@ void KillAll(const std::vector<pid_t>& pids, int signal_number) {
} // namespace
int main(int argc, char** argv) {
- bool short_output = false;
if (argc == 1) {
- LOG(ERROR) << "Usage: " << argv[0] << " [-a] <PID1>... <PIDN>";
+ LOG(ERROR) << "Usage: " << argv[0] << " [-a|-x] <PID1>... <PIDN>";
return EXIT_FAILURE;
}
- if (!strncmp(argv[1], "-a", 2)) {
+ const bool short_output = !strncmp(argv[1], "-a", 2);
+ const bool extended_output = !strncmp(argv[1], "-x", 2);
+ if (short_output || extended_output) {
if (argc == 2) {
- LOG(ERROR) << "Usage: " << argv[0] << " [-a] <PID1>... <PIDN>";
+ LOG(ERROR) << "Usage: " << argv[0] << " [-a|-x] <PID1>... <PIDN>";
return EXIT_FAILURE;
}
- short_output = true;
++argv;
}
std::vector<pid_t> pids;
@@ -476,6 +551,8 @@ int main(int argc, char** argv) {
ClassifyPages(&processes_memory);
if (short_output)
DumpProcessesMemoryMapsInShortFormat(processes_memory);
+ else if (extended_output)
+ DumpProcessesMemoryMapsInExtendedFormat(processes_memory);
else
DumpProcessesMemoryMaps(processes_memory);
return EXIT_SUCCESS;
« no previous file with comments | « no previous file | tools/android/memdump/memsymbols.py » ('j') | tools/android/memdump/memsymbols.py » ('J')

Powered by Google App Engine
This is Rietveld 408576698