Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "components/tracing/common/process_metrics_memory_dump_provider.h" | 5 #include "components/tracing/common/process_metrics_memory_dump_provider.h" |
| 6 | 6 |
| 7 #include <fcntl.h> | 7 #include <fcntl.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include <map> | 10 #include <map> |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 173 pmm->AddVMRegion(region); | 173 pmm->AddVMRegion(region); |
| 174 ++num_valid_regions; | 174 ++num_valid_regions; |
| 175 should_add_current_region = false; | 175 should_add_current_region = false; |
| 176 } | 176 } |
| 177 } | 177 } |
| 178 } | 178 } |
| 179 } | 179 } |
| 180 return num_valid_regions; | 180 return num_valid_regions; |
| 181 } | 181 } |
| 182 | 182 |
| 183 bool GetResidentSizeFromStatmFile(int fd, uint64_t* resident_pages) { | 183 bool GetResidentAndSharedPagesFromStatmFile(int fd, |
| 184 uint64_t* resident_pages, | |
| 185 uint64_t* shared_pages) { | |
| 184 lseek(fd, 0, SEEK_SET); | 186 lseek(fd, 0, SEEK_SET); |
| 185 char line[kMaxLineSize]; | 187 char line[kMaxLineSize]; |
| 186 int res = read(fd, line, kMaxLineSize - 1); | 188 int res = read(fd, line, kMaxLineSize - 1); |
| 187 if (res <= 0) | 189 if (res <= 0) |
| 188 return false; | 190 return false; |
| 189 line[res] = '\0'; | 191 line[res] = '\0'; |
| 190 int num_scanned = sscanf(line, "%*s %" SCNu64, resident_pages); | 192 int num_scanned = |
| 191 return num_scanned == 1; | 193 sscanf(line, "%*s %" SCNu64 " %" SCNu64, resident_pages, shared_pages); |
| 194 return num_scanned == 2; | |
| 192 } | 195 } |
| 193 | 196 |
| 194 #endif // defined(OS_LINUX) || defined(OS_ANDROID) | 197 #endif // defined(OS_LINUX) || defined(OS_ANDROID) |
| 195 | 198 |
| 196 std::unique_ptr<base::ProcessMetrics> CreateProcessMetrics( | 199 std::unique_ptr<base::ProcessMetrics> CreateProcessMetrics( |
| 197 base::ProcessId process) { | 200 base::ProcessId process) { |
| 198 if (process == base::kNullProcessId) | 201 if (process == base::kNullProcessId) |
| 199 return base::ProcessMetrics::CreateCurrentProcessMetrics(); | 202 return base::ProcessMetrics::CreateCurrentProcessMetrics(); |
| 200 #if defined(OS_LINUX) || defined(OS_ANDROID) | 203 #if defined(OS_LINUX) || defined(OS_ANDROID) |
| 201 // Just pass ProcessId instead of handle since they are the same in linux and | 204 // Just pass ProcessId instead of handle since they are the same in linux and |
| (...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 626 #endif // defined(OS_MACOSX) | 629 #endif // defined(OS_MACOSX) |
| 627 if (rss_bytes_for_testing) | 630 if (rss_bytes_for_testing) |
| 628 rss_bytes = rss_bytes_for_testing; | 631 rss_bytes = rss_bytes_for_testing; |
| 629 | 632 |
| 630 // rss_bytes will be 0 if the process ended while dumping. | 633 // rss_bytes will be 0 if the process ended while dumping. |
| 631 if (!rss_bytes) | 634 if (!rss_bytes) |
| 632 return false; | 635 return false; |
| 633 | 636 |
| 634 uint64_t peak_rss_bytes = 0; | 637 uint64_t peak_rss_bytes = 0; |
| 635 | 638 |
| 639 #if defined(OS_LINUX) || defined(OS_ANDROID) | |
| 640 base::trace_event::ProcessMemoryTotals::PlatformPrivateFootprint& footprint = | |
|
Primiano Tucci (use gerrit)
2017/05/03 19:21:21
const auto& footprint = ...?
hjd
2017/05/04 10:46:35
After this the line is *exactly* 80 chars => Best
| |
| 641 pmd->process_totals()->GetPlatformPrivateFootprint(); | |
| 642 | |
| 643 base::ScopedFD autoclose; | |
| 644 int statm_fd = fast_polling_statm_fd_.get(); | |
| 645 if (statm_fd == -1) { | |
| 646 autoclose = OpenStatm(); | |
| 647 statm_fd = autoclose.get(); | |
| 648 } | |
| 649 if (statm_fd != -1) { | |
|
Primiano Tucci (use gerrit)
2017/05/03 19:21:21
I'd just return false if statm_Fd == -1 here. Giv
hjd
2017/05/04 10:46:35
Done.
| |
| 650 static size_t page_size = base::GetPageSize(); | |
|
Primiano Tucci (use gerrit)
2017/05/03 19:21:22
static const size_t kPageSize
hjd
2017/05/04 10:46:35
Done.
| |
| 651 uint64_t resident_pages; | |
| 652 uint64_t shared_pages; | |
| 653 bool success = GetResidentAndSharedPagesFromStatmFile( | |
| 654 statm_fd, &resident_pages, &shared_pages); | |
| 655 if (success) { | |
|
Primiano Tucci (use gerrit)
2017/05/03 19:21:21
ditto, if(!success) return false;
hjd
2017/05/04 10:46:35
Done.
| |
| 656 footprint.rss_anon_bytes = (resident_pages - shared_pages) * page_size; | |
| 657 } | |
| 658 } | |
| 659 #endif // defined(OS_LINUX) | |
|
Primiano Tucci (use gerrit)
2017/05/03 19:21:21
add a // TODO(hjd): implement swap in the next CL.
hjd
2017/05/04 10:46:35
Done.
| |
| 660 | |
| 636 #if !defined(OS_IOS) | 661 #if !defined(OS_IOS) |
| 637 peak_rss_bytes = process_metrics_->GetPeakWorkingSetSize(); | 662 peak_rss_bytes = process_metrics_->GetPeakWorkingSetSize(); |
| 638 #if defined(OS_LINUX) || defined(OS_ANDROID) | 663 #if defined(OS_LINUX) || defined(OS_ANDROID) |
| 639 if (is_rss_peak_resettable_) { | 664 if (is_rss_peak_resettable_) { |
| 640 std::string clear_refs_file = | 665 std::string clear_refs_file = |
| 641 "/proc/" + | 666 "/proc/" + |
| 642 (process_ == base::kNullProcessId ? "self" | 667 (process_ == base::kNullProcessId ? "self" |
| 643 : base::IntToString(process_)) + | 668 : base::IntToString(process_)) + |
| 644 "/clear_refs"; | 669 "/clear_refs"; |
| 645 int clear_refs_fd = open(clear_refs_file.c_str(), O_WRONLY); | 670 int clear_refs_fd = open(clear_refs_file.c_str(), O_WRONLY); |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 669 #endif // !defined(OS_IOS) | 694 #endif // !defined(OS_IOS) |
| 670 | 695 |
| 671 pmd->process_totals()->set_resident_set_bytes(rss_bytes); | 696 pmd->process_totals()->set_resident_set_bytes(rss_bytes); |
| 672 pmd->set_has_process_totals(); | 697 pmd->set_has_process_totals(); |
| 673 pmd->process_totals()->set_peak_resident_set_bytes(peak_rss_bytes); | 698 pmd->process_totals()->set_peak_resident_set_bytes(peak_rss_bytes); |
| 674 | 699 |
| 675 // Returns true even if other metrics failed, since rss is reported. | 700 // Returns true even if other metrics failed, since rss is reported. |
| 676 return true; | 701 return true; |
| 677 } | 702 } |
| 678 | 703 |
| 704 base::ScopedFD ProcessMetricsMemoryDumpProvider::OpenStatm() { | |
| 705 std::string name = | |
| 706 "/proc/" + | |
| 707 (process_ == base::kNullProcessId ? "self" | |
| 708 : base::IntToString(process_)) + | |
| 709 "/statm"; | |
| 710 base::ScopedFD fd = base::ScopedFD(open(name.c_str(), O_RDONLY)); | |
| 711 DCHECK(fd.is_valid()); | |
| 712 return fd; | |
| 713 } | |
| 714 | |
| 679 void ProcessMetricsMemoryDumpProvider::PollFastMemoryTotal( | 715 void ProcessMetricsMemoryDumpProvider::PollFastMemoryTotal( |
| 680 uint64_t* memory_total) { | 716 uint64_t* memory_total) { |
| 681 *memory_total = 0; | 717 *memory_total = 0; |
| 682 #if defined(OS_LINUX) || defined(OS_ANDROID) | 718 #if defined(OS_LINUX) || defined(OS_ANDROID) |
| 719 | |
| 683 int statm_fd = fast_polling_statm_fd_for_testing; | 720 int statm_fd = fast_polling_statm_fd_for_testing; |
| 684 if (statm_fd == -1) { | 721 if (!fast_polling_statm_fd_.is_valid()) |
| 685 if (!fast_polling_statm_fd_.is_valid()) { | 722 fast_polling_statm_fd_ = OpenStatm(); |
| 686 std::string name = "/proc/" + (process_ == base::kNullProcessId | 723 if (statm_fd == -1) |
|
Primiano Tucci (use gerrit)
2017/05/03 19:21:21
I think this is changing the semantic for the for_
hjd
2017/05/04 10:46:35
Done, thanks!
| |
| 687 ? "self" | |
| 688 : base::IntToString(process_)) + | |
| 689 "/statm"; | |
| 690 fast_polling_statm_fd_.reset(open(name.c_str(), O_RDONLY)); | |
| 691 DCHECK(fast_polling_statm_fd_.is_valid()); | |
| 692 } | |
| 693 statm_fd = fast_polling_statm_fd_.get(); | 724 statm_fd = fast_polling_statm_fd_.get(); |
| 694 } | |
| 695 if (statm_fd == -1) | 725 if (statm_fd == -1) |
| 696 return; | 726 return; |
| 697 | 727 |
| 698 uint64_t rss_pages = 0; | 728 uint64_t rss_pages = 0; |
| 699 if (!GetResidentSizeFromStatmFile(statm_fd, &rss_pages)) | 729 uint64_t shared_pages = 0; |
| 730 if (!GetResidentAndSharedPagesFromStatmFile(statm_fd, &rss_pages, | |
| 731 &shared_pages)) | |
| 700 return; | 732 return; |
| 701 | 733 |
| 702 static size_t page_size = base::GetPageSize(); | 734 static size_t page_size = base::GetPageSize(); |
| 703 *memory_total = rss_pages * page_size; | 735 *memory_total = rss_pages * page_size; |
| 704 #else | 736 #else |
| 705 *memory_total = process_metrics_->GetWorkingSetSize(); | 737 *memory_total = process_metrics_->GetWorkingSetSize(); |
| 706 #endif | 738 #endif |
| 707 } | 739 } |
| 708 | 740 |
| 709 void ProcessMetricsMemoryDumpProvider::SuspendFastMemoryPolling() { | 741 void ProcessMetricsMemoryDumpProvider::SuspendFastMemoryPolling() { |
| 710 #if defined(OS_LINUX) || defined(OS_ANDROID) | 742 #if defined(OS_LINUX) || defined(OS_ANDROID) |
| 711 fast_polling_statm_fd_.reset(); | 743 fast_polling_statm_fd_.reset(); |
| 712 #endif | 744 #endif |
| 713 } | 745 } |
| 714 | 746 |
| 715 } // namespace tracing | 747 } // namespace tracing |
| OLD | NEW |