OLD | NEW |
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 <sys/types.h> | 7 #include <sys/types.h> |
8 #include <unistd.h> | 8 #include <unistd.h> |
9 | 9 |
10 #include <algorithm> | 10 #include <algorithm> |
11 #include <cstring> | 11 #include <cstring> |
12 #include <fstream> | 12 #include <fstream> |
13 #include <iostream> | 13 #include <iostream> |
14 #include <limits> | 14 #include <limits> |
15 #include <string> | 15 #include <string> |
16 #include <utility> | 16 #include <utility> |
17 #include <vector> | 17 #include <vector> |
18 | 18 |
19 #include "base/base64.h" | 19 #include "base/base64.h" |
20 #include "base/basictypes.h" | 20 #include "base/basictypes.h" |
21 #include "base/bind.h" | 21 #include "base/bind.h" |
22 #include "base/callback_helpers.h" | 22 #include "base/callback_helpers.h" |
23 #include "base/containers/hash_tables.h" | 23 #include "base/containers/hash_tables.h" |
24 #include "base/file_util.h" | 24 #include "base/file_util.h" |
25 #include "base/files/scoped_file.h" | |
26 #include "base/logging.h" | 25 #include "base/logging.h" |
27 #include "base/strings/string_number_conversions.h" | 26 #include "base/strings/string_number_conversions.h" |
28 #include "base/strings/string_split.h" | 27 #include "base/strings/string_split.h" |
29 #include "base/strings/stringprintf.h" | 28 #include "base/strings/stringprintf.h" |
30 | 29 |
31 const unsigned int kPageSize = getpagesize(); | 30 const unsigned int kPageSize = getpagesize(); |
32 | 31 |
33 namespace { | 32 namespace { |
34 | 33 |
35 class BitSet { | 34 class BitSet { |
(...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
430 memory_map.committed_pages_bits.AsB64String().c_str()); | 429 memory_map.committed_pages_bits.AsB64String().c_str()); |
431 std::cout << buf; | 430 std::cout << buf; |
432 } | 431 } |
433 } | 432 } |
434 } | 433 } |
435 | 434 |
436 bool CollectProcessMemoryInformation(int page_count_fd, | 435 bool CollectProcessMemoryInformation(int page_count_fd, |
437 int page_flags_fd, | 436 int page_flags_fd, |
438 ProcessMemory* process_memory) { | 437 ProcessMemory* process_memory) { |
439 const pid_t pid = process_memory->pid; | 438 const pid_t pid = process_memory->pid; |
440 base::ScopedFD pagemap_fd(open( | 439 int pagemap_fd = open( |
441 base::StringPrintf("/proc/%d/pagemap", pid).c_str(), O_RDONLY)); | 440 base::StringPrintf("/proc/%d/pagemap", pid).c_str(), O_RDONLY); |
442 if (!pagemap_fd.is_valid()) { | 441 if (pagemap_fd < 0) { |
443 PLOG(ERROR) << "open"; | 442 PLOG(ERROR) << "open"; |
444 return false; | 443 return false; |
445 } | 444 } |
| 445 file_util::ScopedFD auto_closer(&pagemap_fd); |
446 std::vector<MemoryMap>* const process_maps = &process_memory->memory_maps; | 446 std::vector<MemoryMap>* const process_maps = &process_memory->memory_maps; |
447 if (!GetProcessMaps(pid, process_maps)) | 447 if (!GetProcessMaps(pid, process_maps)) |
448 return false; | 448 return false; |
449 for (std::vector<MemoryMap>::iterator it = process_maps->begin(); | 449 for (std::vector<MemoryMap>::iterator it = process_maps->begin(); |
450 it != process_maps->end(); ++it) { | 450 it != process_maps->end(); ++it) { |
451 std::vector<PageInfo>* const committed_pages = &it->committed_pages; | 451 std::vector<PageInfo>* const committed_pages = &it->committed_pages; |
452 BitSet* const pages_bits = &it->committed_pages_bits; | 452 BitSet* const pages_bits = &it->committed_pages_bits; |
453 GetPagesForMemoryMap(pagemap_fd.get(), *it, committed_pages, pages_bits); | 453 GetPagesForMemoryMap(pagemap_fd, *it, committed_pages, pages_bits); |
454 SetPagesInfo(page_count_fd, page_flags_fd, committed_pages); | 454 SetPagesInfo(page_count_fd, page_flags_fd, committed_pages); |
455 } | 455 } |
456 return true; | 456 return true; |
457 } | 457 } |
458 | 458 |
459 void KillAll(const std::vector<pid_t>& pids, int signal_number) { | 459 void KillAll(const std::vector<pid_t>& pids, int signal_number) { |
460 for (std::vector<pid_t>::const_iterator it = pids.begin(); it != pids.end(); | 460 for (std::vector<pid_t>::const_iterator it = pids.begin(); it != pids.end(); |
461 ++it) { | 461 ++it) { |
462 kill(*it, signal_number); | 462 kill(*it, signal_number); |
463 } | 463 } |
(...skipping 18 matching lines...) Expand all Loading... |
482 std::vector<pid_t> pids; | 482 std::vector<pid_t> pids; |
483 for (const char* const* ptr = argv + 1; *ptr; ++ptr) { | 483 for (const char* const* ptr = argv + 1; *ptr; ++ptr) { |
484 pid_t pid; | 484 pid_t pid; |
485 if (!base::StringToInt(*ptr, &pid)) | 485 if (!base::StringToInt(*ptr, &pid)) |
486 return EXIT_FAILURE; | 486 return EXIT_FAILURE; |
487 pids.push_back(pid); | 487 pids.push_back(pid); |
488 } | 488 } |
489 | 489 |
490 std::vector<ProcessMemory> processes_memory(pids.size()); | 490 std::vector<ProcessMemory> processes_memory(pids.size()); |
491 { | 491 { |
492 base::ScopedFD page_count_fd(open("/proc/kpagecount", O_RDONLY)); | 492 int page_count_fd = open("/proc/kpagecount", O_RDONLY); |
493 if (!page_count_fd.is_valid()) { | 493 if (page_count_fd < 0) { |
494 PLOG(ERROR) << "open /proc/kpagecount"; | 494 PLOG(ERROR) << "open /proc/kpagecount"; |
495 return EXIT_FAILURE; | 495 return EXIT_FAILURE; |
496 } | 496 } |
497 | 497 |
498 base::ScopedFD page_flags_fd(open("/proc/kpageflags", O_RDONLY)); | 498 int page_flags_fd = open("/proc/kpageflags", O_RDONLY); |
499 if (!page_flags_fd.is_valid()) { | 499 if (page_flags_fd < 0) { |
500 PLOG(ERROR) << "open /proc/kpageflags"; | 500 PLOG(ERROR) << "open /proc/kpageflags"; |
501 return EXIT_FAILURE; | 501 return EXIT_FAILURE; |
502 } | 502 } |
503 | 503 |
| 504 file_util::ScopedFD page_count_fd_closer(&page_count_fd); |
| 505 file_util::ScopedFD page_flags_fd_closer(&page_flags_fd); |
| 506 |
504 base::ScopedClosureRunner auto_resume_processes( | 507 base::ScopedClosureRunner auto_resume_processes( |
505 base::Bind(&KillAll, pids, SIGCONT)); | 508 base::Bind(&KillAll, pids, SIGCONT)); |
506 KillAll(pids, SIGSTOP); | 509 KillAll(pids, SIGSTOP); |
507 for (std::vector<pid_t>::const_iterator it = pids.begin(); it != pids.end(); | 510 for (std::vector<pid_t>::const_iterator it = pids.begin(); it != pids.end(); |
508 ++it) { | 511 ++it) { |
509 ProcessMemory* const process_memory = | 512 ProcessMemory* const process_memory = |
510 &processes_memory[it - pids.begin()]; | 513 &processes_memory[it - pids.begin()]; |
511 process_memory->pid = *it; | 514 process_memory->pid = *it; |
512 if (!CollectProcessMemoryInformation( | 515 if (!CollectProcessMemoryInformation( |
513 page_count_fd.get(), page_flags_fd.get(), process_memory)) { | 516 page_count_fd, page_flags_fd, process_memory)) { |
514 return EXIT_FAILURE; | 517 return EXIT_FAILURE; |
515 } | 518 } |
516 } | 519 } |
517 } | 520 } |
518 | 521 |
519 ClassifyPages(&processes_memory); | 522 ClassifyPages(&processes_memory); |
520 if (short_output) | 523 if (short_output) |
521 DumpProcessesMemoryMapsInShortFormat(processes_memory); | 524 DumpProcessesMemoryMapsInShortFormat(processes_memory); |
522 else | 525 else |
523 DumpProcessesMemoryMapsInExtendedFormat(processes_memory); | 526 DumpProcessesMemoryMapsInExtendedFormat(processes_memory); |
524 return EXIT_SUCCESS; | 527 return EXIT_SUCCESS; |
525 } | 528 } |
OLD | NEW |