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

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: Copyright nit 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') | no next file with comments »
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..26035b29b0b67185c3700fa021c5242fb904bacc 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 {
+ public:
+ void resize(size_t nbits) {
+ data_.resize((nbits + 7) / 8);
+ }
+
+ void set(uint32 bit) {
+ const uint32 byte_idx = bit / 8;
+ CHECK(byte_idx < data_.size());
+ data_[byte_idx] |= (1 << (bit & 7));
+ }
+
+ std::string AsB64String() const {
+ std::string bits(&data_[0], data_.size());
+ std::string b64_string;
+ base::Base64Encode(bits, &b64_string);
+ return b64_string;
+ }
+
+ private:
+ 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 bitset reflecting the present bit for all the
+ // 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.resize(
+ (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,40 @@ 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);
+ 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(),
+ memory_map.committed_pages_bits.AsB64String().c_str());
+ std::cout << buf;
+ }
+ }
+}
+
bool CollectProcessMemoryInformation(int page_count_fd,
int page_flags_fd,
ProcessMemory* process_memory) {
@@ -404,7 +474,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* const pages_bits = &it->committed_pages_bits;
+ GetPagesForMemoryMap(pagemap_fd, *it, committed_pages, pages_bits);
SetPagesInfo(page_count_fd, page_flags_fd, committed_pages);
}
return true;
@@ -420,17 +491,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 +547,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') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698