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

Side by Side Diff: tools/android/memdump/memdump.cc

Issue 1549203002: Switch to standard integer types in tools/. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 12 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 unified diff | Download patch
« no previous file with comments | « tools/android/md5sum/md5sum.cc ('k') | tools/battor_agent/battor_agent_bin.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <fcntl.h> 5 #include <fcntl.h>
6 #include <signal.h> 6 #include <signal.h>
7 #include <stddef.h>
8 #include <stdint.h>
7 #include <sys/types.h> 9 #include <sys/types.h>
8 #include <unistd.h> 10 #include <unistd.h>
9 11
10 #include <algorithm> 12 #include <algorithm>
11 #include <cstring> 13 #include <cstring>
12 #include <fstream> 14 #include <fstream>
13 #include <iostream> 15 #include <iostream>
14 #include <limits> 16 #include <limits>
15 #include <string> 17 #include <string>
16 #include <utility> 18 #include <utility>
17 #include <vector> 19 #include <vector>
18 20
19 #include "base/base64.h" 21 #include "base/base64.h"
20 #include "base/basictypes.h"
21 #include "base/bind.h" 22 #include "base/bind.h"
22 #include "base/callback_helpers.h" 23 #include "base/callback_helpers.h"
23 #include "base/containers/hash_tables.h" 24 #include "base/containers/hash_tables.h"
24 #include "base/files/file_util.h" 25 #include "base/files/file_util.h"
25 #include "base/files/scoped_file.h" 26 #include "base/files/scoped_file.h"
26 #include "base/format_macros.h" 27 #include "base/format_macros.h"
27 #include "base/logging.h" 28 #include "base/logging.h"
28 #include "base/strings/string_number_conversions.h" 29 #include "base/strings/string_number_conversions.h"
29 #include "base/strings/string_split.h" 30 #include "base/strings/string_split.h"
30 #include "base/strings/stringprintf.h" 31 #include "base/strings/stringprintf.h"
31 32
32 const unsigned int kPageSize = getpagesize(); 33 const unsigned int kPageSize = getpagesize();
33 34
34 namespace { 35 namespace {
35 36
36 class BitSet { 37 class BitSet {
37 public: 38 public:
38 void resize(size_t nbits) { 39 void resize(size_t nbits) {
39 data_.resize((nbits + 7) / 8); 40 data_.resize((nbits + 7) / 8);
40 } 41 }
41 42
42 void set(uint32 bit) { 43 void set(uint32_t bit) {
43 const uint32 byte_idx = bit / 8; 44 const uint32_t byte_idx = bit / 8;
44 CHECK(byte_idx < data_.size()); 45 CHECK(byte_idx < data_.size());
45 data_[byte_idx] |= (1 << (bit & 7)); 46 data_[byte_idx] |= (1 << (bit & 7));
46 } 47 }
47 48
48 std::string AsB64String() const { 49 std::string AsB64String() const {
49 // Simple optimization: strip trailing zero bytes from the bitmap. 50 // Simple optimization: strip trailing zero bytes from the bitmap.
50 // For instance, if a region has 32 pages but only the first 9 are resident, 51 // For instance, if a region has 32 pages but only the first 9 are resident,
51 // The full bitmap would be 0xff 0x01 0x00 0x00, the stripped one 0xff 0x01. 52 // The full bitmap would be 0xff 0x01 0x00 0x00, the stripped one 0xff 0x01.
52 // It can save up to some seconds when printing large mmaps, in particular 53 // It can save up to some seconds when printing large mmaps, in particular
53 // in presence of large virtual address space reservations (where none of 54 // in presence of large virtual address space reservations (where none of
54 // the pages are resident). 55 // the pages are resident).
55 size_t end = data_.size(); 56 size_t end = data_.size();
56 while (end > 0 && data_[end - 1] == '\0') 57 while (end > 0 && data_[end - 1] == '\0')
57 --end; 58 --end;
58 std::string bits(&data_[0], end); 59 std::string bits(&data_[0], end);
59 std::string b64_string; 60 std::string b64_string;
60 base::Base64Encode(bits, &b64_string); 61 base::Base64Encode(bits, &b64_string);
61 return b64_string; 62 return b64_string;
62 } 63 }
63 64
64 private: 65 private:
65 std::vector<char> data_; 66 std::vector<char> data_;
66 }; 67 };
67 68
68 // An entry in /proc/<pid>/pagemap. 69 // An entry in /proc/<pid>/pagemap.
69 struct PageMapEntry { 70 struct PageMapEntry {
70 uint64 page_frame_number : 55; 71 uint64_t page_frame_number : 55;
71 uint unused : 8; 72 uint unused : 8;
72 uint present : 1; 73 uint present : 1;
73 }; 74 };
74 75
75 // Describes a memory page. 76 // Describes a memory page.
76 struct PageInfo { 77 struct PageInfo {
77 int64 page_frame_number; // Physical page id, also known as PFN. 78 int64_t page_frame_number; // Physical page id, also known as PFN.
78 int64 flags; 79 int64_t flags;
79 int32 times_mapped; 80 int32_t times_mapped;
80 }; 81 };
81 82
82 struct PageCount { 83 struct PageCount {
83 PageCount() : total_count(0), unevictable_count(0) {} 84 PageCount() : total_count(0), unevictable_count(0) {}
84 85
85 int total_count; 86 int total_count;
86 int unevictable_count; 87 int unevictable_count;
87 }; 88 };
88 89
89 struct MemoryMap { 90 struct MemoryMap {
90 std::string name; 91 std::string name;
91 std::string flags; 92 std::string flags;
92 uint64 start_address; 93 uint64_t start_address;
93 uint64 end_address; 94 uint64_t end_address;
94 uint64 offset; 95 uint64_t offset;
95 PageCount private_pages; 96 PageCount private_pages;
96 // app_shared_pages[i] contains the number of pages mapped in i+2 processes 97 // app_shared_pages[i] contains the number of pages mapped in i+2 processes
97 // (only among the processes that are being analyzed). 98 // (only among the processes that are being analyzed).
98 std::vector<PageCount> app_shared_pages; 99 std::vector<PageCount> app_shared_pages;
99 PageCount other_shared_pages; 100 PageCount other_shared_pages;
100 std::vector<PageInfo> committed_pages; 101 std::vector<PageInfo> committed_pages;
101 // committed_pages_bits is a bitset reflecting the present bit for all the 102 // committed_pages_bits is a bitset reflecting the present bit for all the
102 // virtual pages of the mapping. 103 // virtual pages of the mapping.
103 BitSet committed_pages_bits; 104 BitSet committed_pages_bits;
104 }; 105 };
(...skipping 11 matching lines...) Expand all
116 const int KPF_MLOCKED = 33; 117 const int KPF_MLOCKED = 33;
117 118
118 return (page_info.flags & ((1ll << KPF_DIRTY) | 119 return (page_info.flags & ((1ll << KPF_DIRTY) |
119 (1ll << KPF_ANON) | 120 (1ll << KPF_ANON) |
120 (1ll << KPF_UNEVICTABLE) | 121 (1ll << KPF_UNEVICTABLE) |
121 (1ll << KPF_MLOCKED))) ? 122 (1ll << KPF_MLOCKED))) ?
122 true : false; 123 true : false;
123 } 124 }
124 125
125 // Number of times a physical page is mapped in a process. 126 // Number of times a physical page is mapped in a process.
126 typedef base::hash_map<uint64, int> PFNMap; 127 typedef base::hash_map<uint64_t, int> PFNMap;
127 128
128 // Parses lines from /proc/<PID>/maps, e.g.: 129 // Parses lines from /proc/<PID>/maps, e.g.:
129 // 401e7000-401f5000 r-xp 00000000 103:02 158 /system/bin/linker 130 // 401e7000-401f5000 r-xp 00000000 103:02 158 /system/bin/linker
130 bool ParseMemoryMapLine(const std::string& line, 131 bool ParseMemoryMapLine(const std::string& line,
131 std::vector<std::string>* tokens, 132 std::vector<std::string>* tokens,
132 MemoryMap* memory_map) { 133 MemoryMap* memory_map) {
133 *tokens = base::SplitString( 134 *tokens = base::SplitString(
134 line, " ", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); 135 line, " ", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
135 if (tokens->size() < 2) 136 if (tokens->size() < 2)
136 return false; 137 return false;
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
206 // provided memory map. 207 // provided memory map.
207 bool GetPagesForMemoryMap(int pagemap_fd, 208 bool GetPagesForMemoryMap(int pagemap_fd,
208 const MemoryMap& memory_map, 209 const MemoryMap& memory_map,
209 std::vector<PageInfo>* committed_pages, 210 std::vector<PageInfo>* committed_pages,
210 BitSet* committed_pages_bits) { 211 BitSet* committed_pages_bits) {
211 const off64_t offset = memory_map.start_address / kPageSize; 212 const off64_t offset = memory_map.start_address / kPageSize;
212 if (lseek64(pagemap_fd, offset * sizeof(PageMapEntry), SEEK_SET) < 0) { 213 if (lseek64(pagemap_fd, offset * sizeof(PageMapEntry), SEEK_SET) < 0) {
213 PLOG(ERROR) << "lseek"; 214 PLOG(ERROR) << "lseek";
214 return false; 215 return false;
215 } 216 }
216 for (uint64 addr = memory_map.start_address, page_index = 0; 217 for (uint64_t addr = memory_map.start_address, page_index = 0;
217 addr < memory_map.end_address; 218 addr < memory_map.end_address; addr += kPageSize, ++page_index) {
218 addr += kPageSize, ++page_index) {
219 DCHECK_EQ(0u, addr % kPageSize); 219 DCHECK_EQ(0u, addr % kPageSize);
220 PageMapEntry page_map_entry = {}; 220 PageMapEntry page_map_entry = {};
221 static_assert(sizeof(PageMapEntry) == sizeof(uint64), "unexpected size"); 221 static_assert(sizeof(PageMapEntry) == sizeof(uint64_t), "unexpected size");
222 ssize_t bytes = read(pagemap_fd, &page_map_entry, sizeof(page_map_entry)); 222 ssize_t bytes = read(pagemap_fd, &page_map_entry, sizeof(page_map_entry));
223 if (bytes != sizeof(PageMapEntry) && bytes != 0) { 223 if (bytes != sizeof(PageMapEntry) && bytes != 0) {
224 PLOG(ERROR) << "read"; 224 PLOG(ERROR) << "read";
225 return false; 225 return false;
226 } 226 }
227 if (page_map_entry.present) { // Ignore non-committed pages. 227 if (page_map_entry.present) { // Ignore non-committed pages.
228 if (page_map_entry.page_frame_number == 0) 228 if (page_map_entry.page_frame_number == 0)
229 continue; 229 continue;
230 PageInfo page_info = {}; 230 PageInfo page_info = {};
231 page_info.page_frame_number = page_map_entry.page_frame_number; 231 page_info.page_frame_number = page_map_entry.page_frame_number;
232 committed_pages->push_back(page_info); 232 committed_pages->push_back(page_info);
233 committed_pages_bits->set(page_index); 233 committed_pages_bits->set(page_index);
234 } 234 }
235 } 235 }
236 return true; 236 return true;
237 } 237 }
238 238
239 // Fills |committed_pages| with mapping count and flags information gathered 239 // Fills |committed_pages| with mapping count and flags information gathered
240 // looking-up /proc/kpagecount and /proc/kpageflags. 240 // looking-up /proc/kpagecount and /proc/kpageflags.
241 bool SetPagesInfo(int pagecount_fd, 241 bool SetPagesInfo(int pagecount_fd,
242 int pageflags_fd, 242 int pageflags_fd,
243 std::vector<PageInfo>* pages) { 243 std::vector<PageInfo>* pages) {
244 for (std::vector<PageInfo>::iterator it = pages->begin(); 244 for (std::vector<PageInfo>::iterator it = pages->begin();
245 it != pages->end(); ++it) { 245 it != pages->end(); ++it) {
246 PageInfo* const page_info = &*it; 246 PageInfo* const page_info = &*it;
247 int64 times_mapped; 247 int64_t times_mapped;
248 if (!ReadFromFileAtOffset( 248 if (!ReadFromFileAtOffset(
249 pagecount_fd, page_info->page_frame_number, &times_mapped)) { 249 pagecount_fd, page_info->page_frame_number, &times_mapped)) {
250 return false; 250 return false;
251 } 251 }
252 DCHECK(times_mapped <= std::numeric_limits<int32_t>::max()); 252 DCHECK(times_mapped <= std::numeric_limits<int32_t>::max());
253 page_info->times_mapped = static_cast<int32>(times_mapped); 253 page_info->times_mapped = static_cast<int32_t>(times_mapped);
254 254
255 int64 page_flags; 255 int64_t page_flags;
256 if (!ReadFromFileAtOffset( 256 if (!ReadFromFileAtOffset(
257 pageflags_fd, page_info->page_frame_number, &page_flags)) { 257 pageflags_fd, page_info->page_frame_number, &page_flags)) {
258 return false; 258 return false;
259 } 259 }
260 page_info->flags = page_flags; 260 page_info->flags = page_flags;
261 } 261 }
262 return true; 262 return true;
263 } 263 }
264 264
265 // Fills in the provided vector of Page Frame Number maps. This lets 265 // Fills in the provided vector of Page Frame Number maps. This lets
(...skipping 19 matching lines...) Expand all
285 } 285 }
286 } 286 }
287 287
288 // Sets the private_count/app_shared_pages/other_shared_count fields of the 288 // Sets the private_count/app_shared_pages/other_shared_count fields of the
289 // provided memory maps for each process. 289 // provided memory maps for each process.
290 void ClassifyPages(std::vector<ProcessMemory>* processes_memory) { 290 void ClassifyPages(std::vector<ProcessMemory>* processes_memory) {
291 std::vector<PFNMap> pfn_maps(processes_memory->size()); 291 std::vector<PFNMap> pfn_maps(processes_memory->size());
292 FillPFNMaps(*processes_memory, &pfn_maps); 292 FillPFNMaps(*processes_memory, &pfn_maps);
293 // Hash set keeping track of the physical pages mapped in a single process so 293 // Hash set keeping track of the physical pages mapped in a single process so
294 // that they can be counted only once. 294 // that they can be counted only once.
295 base::hash_set<uint64> physical_pages_mapped_in_process; 295 base::hash_set<uint64_t> physical_pages_mapped_in_process;
296 296
297 for (std::vector<ProcessMemory>::iterator it = processes_memory->begin(); 297 for (std::vector<ProcessMemory>::iterator it = processes_memory->begin();
298 it != processes_memory->end(); ++it) { 298 it != processes_memory->end(); ++it) {
299 std::vector<MemoryMap>* const memory_maps = &it->memory_maps; 299 std::vector<MemoryMap>* const memory_maps = &it->memory_maps;
300 physical_pages_mapped_in_process.clear(); 300 physical_pages_mapped_in_process.clear();
301 for (std::vector<MemoryMap>::iterator it = memory_maps->begin(); 301 for (std::vector<MemoryMap>::iterator it = memory_maps->begin();
302 it != memory_maps->end(); ++it) { 302 it != memory_maps->end(); ++it) {
303 MemoryMap* const memory_map = &*it; 303 MemoryMap* const memory_map = &*it;
304 const size_t processes_count = processes_memory->size(); 304 const size_t processes_count = processes_memory->size();
305 memory_map->app_shared_pages.resize(processes_count - 1); 305 memory_map->app_shared_pages.resize(processes_count - 1);
306 const std::vector<PageInfo>& pages = memory_map->committed_pages; 306 const std::vector<PageInfo>& pages = memory_map->committed_pages;
307 for (std::vector<PageInfo>::const_iterator it = pages.begin(); 307 for (std::vector<PageInfo>::const_iterator it = pages.begin();
308 it != pages.end(); ++it) { 308 it != pages.end(); ++it) {
309 const PageInfo& page_info = *it; 309 const PageInfo& page_info = *it;
310 if (page_info.times_mapped == 1) { 310 if (page_info.times_mapped == 1) {
311 ++memory_map->private_pages.total_count; 311 ++memory_map->private_pages.total_count;
312 if (PageIsUnevictable(page_info)) 312 if (PageIsUnevictable(page_info))
313 ++memory_map->private_pages.unevictable_count; 313 ++memory_map->private_pages.unevictable_count;
314 continue; 314 continue;
315 } 315 }
316 const uint64 page_frame_number = page_info.page_frame_number; 316 const uint64_t page_frame_number = page_info.page_frame_number;
317 const std::pair<base::hash_set<uint64>::iterator, bool> result = 317 const std::pair<base::hash_set<uint64_t>::iterator, bool> result =
318 physical_pages_mapped_in_process.insert(page_frame_number); 318 physical_pages_mapped_in_process.insert(page_frame_number);
319 const bool did_insert = result.second; 319 const bool did_insert = result.second;
320 if (!did_insert) { 320 if (!did_insert) {
321 // This physical page (mapped multiple times in the same process) was 321 // This physical page (mapped multiple times in the same process) was
322 // already counted. 322 // already counted.
323 continue; 323 continue;
324 } 324 }
325 // See if the current physical page is also mapped in the other 325 // See if the current physical page is also mapped in the other
326 // processes that are being analyzed. 326 // processes that are being analyzed.
327 int times_mapped = 0; 327 int times_mapped = 0;
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
525 } 525 }
526 } 526 }
527 527
528 ClassifyPages(&processes_memory); 528 ClassifyPages(&processes_memory);
529 if (short_output) 529 if (short_output)
530 DumpProcessesMemoryMapsInShortFormat(processes_memory); 530 DumpProcessesMemoryMapsInShortFormat(processes_memory);
531 else 531 else
532 DumpProcessesMemoryMapsInExtendedFormat(processes_memory); 532 DumpProcessesMemoryMapsInExtendedFormat(processes_memory);
533 return EXIT_SUCCESS; 533 return EXIT_SUCCESS;
534 } 534 }
OLDNEW
« no previous file with comments | « tools/android/md5sum/md5sum.cc ('k') | tools/battor_agent/battor_agent_bin.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698