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" |
25 #include "base/logging.h" | 26 #include "base/logging.h" |
26 #include "base/strings/string_number_conversions.h" | 27 #include "base/strings/string_number_conversions.h" |
27 #include "base/strings/string_split.h" | 28 #include "base/strings/string_split.h" |
28 #include "base/strings/stringprintf.h" | 29 #include "base/strings/stringprintf.h" |
29 | 30 |
30 const unsigned int kPageSize = getpagesize(); | 31 const unsigned int kPageSize = getpagesize(); |
31 | 32 |
32 namespace { | 33 namespace { |
33 | 34 |
34 class BitSet { | 35 class BitSet { |
(...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
429 memory_map.committed_pages_bits.AsB64String().c_str()); | 430 memory_map.committed_pages_bits.AsB64String().c_str()); |
430 std::cout << buf; | 431 std::cout << buf; |
431 } | 432 } |
432 } | 433 } |
433 } | 434 } |
434 | 435 |
435 bool CollectProcessMemoryInformation(int page_count_fd, | 436 bool CollectProcessMemoryInformation(int page_count_fd, |
436 int page_flags_fd, | 437 int page_flags_fd, |
437 ProcessMemory* process_memory) { | 438 ProcessMemory* process_memory) { |
438 const pid_t pid = process_memory->pid; | 439 const pid_t pid = process_memory->pid; |
439 int pagemap_fd = open( | 440 base::ScopedFD pagemap_fd(open( |
440 base::StringPrintf("/proc/%d/pagemap", pid).c_str(), O_RDONLY); | 441 base::StringPrintf("/proc/%d/pagemap", pid).c_str(), O_RDONLY)); |
441 if (pagemap_fd < 0) { | 442 if (!pagemap_fd) { |
442 PLOG(ERROR) << "open"; | 443 PLOG(ERROR) << "open"; |
443 return false; | 444 return false; |
444 } | 445 } |
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, *it, committed_pages, pages_bits); | 453 GetPagesForMemoryMap(pagemap_fd.get(), *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 int page_count_fd = open("/proc/kpagecount", O_RDONLY); | 492 base::ScopedFD page_count_fd(open("/proc/kpagecount", O_RDONLY)); |
493 if (page_count_fd < 0) { | 493 if (!page_count_fd) { |
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 int page_flags_fd = open("/proc/kpageflags", O_RDONLY); | 498 base::ScopedFD page_flags_fd(open("/proc/kpageflags", O_RDONLY)); |
499 if (page_flags_fd < 0) { | 499 if (!page_flags_fd) { |
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 | |
507 base::ScopedClosureRunner auto_resume_processes( | 504 base::ScopedClosureRunner auto_resume_processes( |
508 base::Bind(&KillAll, pids, SIGCONT)); | 505 base::Bind(&KillAll, pids, SIGCONT)); |
509 KillAll(pids, SIGSTOP); | 506 KillAll(pids, SIGSTOP); |
510 for (std::vector<pid_t>::const_iterator it = pids.begin(); it != pids.end(); | 507 for (std::vector<pid_t>::const_iterator it = pids.begin(); it != pids.end(); |
511 ++it) { | 508 ++it) { |
512 ProcessMemory* const process_memory = | 509 ProcessMemory* const process_memory = |
513 &processes_memory[it - pids.begin()]; | 510 &processes_memory[it - pids.begin()]; |
514 process_memory->pid = *it; | 511 process_memory->pid = *it; |
515 if (!CollectProcessMemoryInformation( | 512 if (!CollectProcessMemoryInformation( |
516 page_count_fd, page_flags_fd, process_memory)) { | 513 page_count_fd.get(), page_flags_fd.get(), process_memory)) { |
517 return EXIT_FAILURE; | 514 return EXIT_FAILURE; |
518 } | 515 } |
519 } | 516 } |
520 } | 517 } |
521 | 518 |
522 ClassifyPages(&processes_memory); | 519 ClassifyPages(&processes_memory); |
523 if (short_output) | 520 if (short_output) |
524 DumpProcessesMemoryMapsInShortFormat(processes_memory); | 521 DumpProcessesMemoryMapsInShortFormat(processes_memory); |
525 else | 522 else |
526 DumpProcessesMemoryMapsInExtendedFormat(processes_memory); | 523 DumpProcessesMemoryMapsInExtendedFormat(processes_memory); |
527 return EXIT_SUCCESS; | 524 return EXIT_SUCCESS; |
528 } | 525 } |
OLD | NEW |