Skip to content

cobalt/metrics: Complete Cobalt-specific granular memory tracking implementation#10014

Open
Awallky wants to merge 11 commits intoyoutube:mainfrom
Awallky:granular-memory-port
Open

cobalt/metrics: Complete Cobalt-specific granular memory tracking implementation#10014
Awallky wants to merge 11 commits intoyoutube:mainfrom
Awallky:granular-memory-port

Conversation

@Awallky
Copy link
Copy Markdown
Contributor

@Awallky Awallky commented Apr 14, 2026

This commit finalizes the granular memory tracking implementation for Cobalt.
It resolves merge conflicts, adds specific coverage for Cobalt libraries in
browser tests, and adds robustness tests based on code review feedback.

  • Resolve merge conflicts in granular_memory_browsertest.cc and os_metrics.
  • Fix GN check error in content/test/BUILD.gn.
  • Add CobaltSpecificMetrics test to verify actual library categorization.
  • Add robustness tests for large values and unexpected units in unit tests.

Bug: 494004530

@github-actions
Copy link
Copy Markdown
Contributor

🤖 Gemini Suggested Commit Message


cobalt: Add detailed memory metrics infrastructure

Introduce CobaltDetailedMetricsDelegate to categorize memory mappings
from /proc/self/smaps into Cobalt-specific groups such as CobaltCore,
V8, and Malloc. This delegate is integrated into the memory
instrumentation service to enable fine-grained memory monitoring.

Update memory metrics emitters to log these new detailed statistics to UMA,
providing a deeper understanding of Cobalt's memory footprint.
Refactor smaps parsing in base/debug/proc_maps_linux.cc for
efficiency and robustness, utilizing string_view and avoiding sscanf.
Move OS memory dump operations to a background thread to prevent
blocking the main thread during memory collection.
New browser tests are added to verify correct categorization and data
collection.

Bug: 494004530

💡 Pro Tips for a Better Commit Message:

  1. Influence the Result: Want to change the output? You can write custom prompts or instructions directly in the Pull Request description. The model uses that text to generate the message.
  2. Re-run the Generator: Post a comment with: /generate-commit-message

@Awallky Awallky force-pushed the granular-memory-port branch from 78dd42e to 45bd7e3 Compare April 14, 2026 04:48
@Awallky Awallky marked this pull request as ready for review April 14, 2026 04:59
@Awallky Awallky requested review from a team as code owners April 14, 2026 04:59
@Awallky Awallky requested a review from oxve April 14, 2026 04:59
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request implements a granular memory metrics collection system for Cobalt, introducing a DetailedMetricsDelegate to categorize memory mappings from /proc/self/smaps. Key changes include refactoring proc_maps_linux.cc to use std::string_view and base::SplitStringPiece for more efficient parsing, and updating the memory instrumentation service to support project-specific detailed metrics. Review feedback highlights opportunities to improve the robustness of the parsing logic by using pointer arithmetic instead of string searching for path extraction, handling potential numeric overflows by saturating to the maximum size_t value, and maintaining larger buffer sizes to prevent truncation of long smaps lines.

Comment on lines +214 to +222
size_t dev_pos = lines[i].find(tokens[3]);
size_t inode_pos = lines[i].find(tokens[4], dev_pos + tokens[3].size());
if (inode_pos != std::string_view::npos) {
size_t path_pos =
lines[i].find_first_not_of(' ', inode_pos + tokens[4].size());
if (path_pos != std::string_view::npos) {
region.path.assign(lines[i].substr(path_pos));
}
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The logic to find the path position using find() on token strings is fragile. It can return incorrect indices if the device or inode strings appear earlier in the line (e.g., as part of the hex address range or offset). Since tokens[4] is a std::string_view that points directly into the lines[i] buffer, you can calculate the exact position using pointer arithmetic, which is safer and more efficient.

      const char* line_start = lines[i].data();
      const char* inode_end = tokens[4].data() + tokens[4].size();
      size_t inode_end_pos = static_cast<size_t>(inode_end - line_start);
      size_t path_pos = lines[i].find_first_not_of(' ', inode_end_pos);
      if (path_pos != std::string_view::npos) {
        region.path.assign(lines[i].substr(path_pos));
      }

Comment on lines +216 to +229
size_t dev_pos = header_line.find(tokens[3]);
if (dev_pos != std::string_view::npos) {
size_t inode_pos =
header_line.find(tokens[4], dev_pos + tokens[3].size());
if (inode_pos != std::string_view::npos) {
size_t filename_pos =
header_line.find_first_not_of(' ', inode_pos + tokens[4].size());
if (filename_pos != std::string_view::npos) {
region->mapped_file = std::string(header_line.substr(filename_pos));
base::TrimWhitespaceASCII(region->mapped_file, base::TRIM_ALL,
&region->mapped_file);
}
}
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Similar to the issue in base/debug/proc_maps_linux.cc, using find() to locate the filename position is unreliable because the device or inode strings might match substrings in earlier fields like the address range. Use pointer arithmetic with the std::string_view tokens to determine the correct offset.

    const char* line_start = header_line.data();
    const char* inode_end = tokens[4].data() + tokens[4].size();
    size_t inode_end_pos = static_cast<size_t>(inode_end - line_start);
    size_t filename_pos = header_line.find_first_not_of(' ', inode_end_pos);
    if (filename_pos != std::string_view::npos) {
      region->mapped_file = std::string(header_line.substr(filename_pos));
      base::TrimWhitespaceASCII(region->mapped_file, base::TRIM_ALL,
                                &region->mapped_file);
    }

if (base::StringToSizeT(tokens[1], &val)) {
base::CheckedNumeric<size_t> val_bytes = val;
val_bytes *= 1024;
tmp[key] = val_bytes.ValueOrDefault(0);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Using ValueOrDefault(0) on overflow can lead to incorrect metrics reporting if the value exceeds the capacity of size_t (which is possible on 32-bit platforms). It is safer to saturate to the maximum possible value.

Suggested change
tmp[key] = val_bytes.ValueOrDefault(0);
tmp[key] = val_bytes.ValueOrDefault(std::numeric_limits<size_t>::max());


if (!res)
return std::vector<VmRegionPtr>();
char line[2048];
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The buffer size for reading smaps lines has been reduced from 4096 to 2048. While 2048 is often enough, smaps lines containing very long paths can exceed this limit. It is safer to maintain the previous limit of 4096 to avoid truncation issues during parsing.

Suggested change
char line[2048];
char line[4096];

@Awallky Awallky changed the title cobalt/metrics: Add CobaltDetailedMetricsDelegate and enable metrics cobalt/metrics: Complete Cobalt-specific granular memory tracking implementation Apr 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant