Skip to content

feat: Implement granular heap walking for Linux (Resolves #12)#91

Merged
SickleFire merged 1 commit into
SickleFire:devfrom
Samanyu-dev:fix-walk-heap-granular-linux
Jul 8, 2026
Merged

feat: Implement granular heap walking for Linux (Resolves #12)#91
SickleFire merged 1 commit into
SickleFire:devfrom
Samanyu-dev:fix-walk-heap-granular-linux

Conversation

@Samanyu-dev

Copy link
Copy Markdown
Collaborator

Pull Request Title

feat(linux): implement granular heap walking for Linux

Description

This PR splits the existing walk_heap function in src/os/linux.rs into two distinct functions to support granular heap parsing on Linux, achieving feature parity with Windows.

  • walk_heap now returns the entire [heap] region as a single HeapBlock based on /proc/<pid>/maps (improving default performance).
  • walk_heap_granular handles the detailed glibc malloc chunk parsing via /proc/<pid>/mem.
  • Updates get_heap_blocks in src/ui/commands.rs to invoke the granular variant on Linux when requested.

Fixes #12

Code Snippets & Explanations

1. Faster Default Heap Walk (walk_heap)
Previously, walk_heap on Linux would automatically parse detailed glibc memory blocks, slowing it down. Now, it treats the entire heap as a single region similar to the non-granular default behavior on Windows:

pub fn walk_heap(pid: u32) -> Vec<HeapBlock> {
    let mut blocks = Vec::new();
    // ... finds the start and end in /proc/<pid>/maps
    
    if heap_start > 0 && heap_end > heap_start {
        // Return a single block representing the entire region
        blocks.push(HeapBlock {
            address: heap_start,
            size: heap_end - heap_start,
            is_free: false,
            vm_protect,
        });
    }

    blocks
}

2. Granular Heap Walk Implementation (walk_heap_granular)
The previous detailed logic reading glibc chunk structures was shifted into walk_heap_granular:

/// Reads `/proc/<pid>/smaps` (or `/proc/<pid>/mem`) and returns individual glibc heap chunks.
pub fn walk_heap_granular(pid: u32) -> Vec<HeapBlock> {
    use std::io::{Read, Seek, SeekFrom};
    let mut blocks = Vec::new();
    // ... finds the heap region in /proc/<pid>/maps

    // Reads /proc/<pid>/mem to map exact chunk headers and allocations
    let mem_path = format!("/proc/{}/mem", pid);
    let mut mem = std::fs::File::open(&mem_path).unwrap();
    // ... processes each chunk's header to identify allocations individually

3. Invoking the Granular Walk on Linux
Updated get_heap_blocks in src/ui/commands.rs to call our newly exposed granular Linux logic when _granular is toggled on:

fn get_heap_blocks(pid: u32, _granular: bool) -> Vec<HeapBlock> {
    let mem = os::provider();
    // ... Windows logic ...

    #[cfg(target_os = "linux")]
    {
        if _granular {
            // Uses detailed parsing when granular mode is toggled (-h -g)
            crate::os::walk_heap_granular(pid)
        } else {
            // Default fast parsing
            mem.walk_heap(pid).unwrap_or_default()
        }
    }
}

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update
  • Chore / Refactor

Related issues

How Has This Been Tested

  • Unit tests: Verified compilation and no regressions.
  • Integration tests: cargo test passes existing project constraints.
  • Manual steps: Executed cargo check and cargo build to ensure the new Linux specific conditionals compile successfully without unused variable warnings.
  • Platform tested on: Linux (Ubuntu) / macOS

Checklist

  • I have read the CONTRIBUTING.md and followed the repo guidelines.
  • Code builds locally (cargo build --release)
  • All tests pass (cargo test)
  • New and existing tests cover my changes
  • I added/updated documentation where applicable
  • I updated CHANGELOG or release notes if needed

CI and Performance Notes

  • CI status: CI is expected to pass as normal.
  • Performance impact: The default walk_heap on Linux is now significantly faster since it no longer parses individual malloc chunks. Granular chunk parsing is properly deferred to walk_heap_granular when explicitly enabled.

Screenshots or Logs

(N/A)

Release Notes

  • Release type: minor
  • Notes for release manager: Added walk_heap_granular support for Linux to maintain feature parity with Windows. Default walk_heap on Linux is now more performant as it treats the entire heap region as a single contiguous block.

@Samanyu-dev Samanyu-dev requested a review from SickleFire July 8, 2026 08:48
@Samanyu-dev Samanyu-dev self-assigned this Jul 8, 2026
Copilot AI review requested due to automatic review settings July 8, 2026 08:48
@Samanyu-dev Samanyu-dev added the missing implementation Feature that has not been implemented yet label Jul 8, 2026

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@SickleFire SickleFire left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Code quality: Well-structured refactoring that preserves existing behavior while improving default performance
Platform coverage: Properly gated with #[cfg(target_os = "linux")] to avoid affecting other platforms

LGTM! Approved. Merging this in!

@SickleFire SickleFire merged commit b791625 into SickleFire:dev Jul 8, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

missing implementation Feature that has not been implemented yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants