Skip to content

Show memory map of highlighted process - #2148

Open
pwilke wants to merge 3 commits into
htop-dev:mainfrom
pwilke:mem-maps
Open

pwilke wants to merge 3 commits into
htop-dev:mainfrom
pwilke:mem-maps

Conversation

@pwilke

@pwilke pwilke commented Nov 5, 2026 •

Copy link
Copy Markdown

What

Adds a new info-screen that shows a process's memory map (/proc/<pid>/maps),
opened with the r key (for memory regions) from the process list — alongside the existing
per-process screens (e environment, l lsof, s strace, x locks).

Inspecting a process's mappings currently means leaving htop for pmap <pid> or
cat /proc/<pid>/maps. This brings it inline, consistent with htop's other
InfoScreen views.

Details

  • New MapsScreen (an InfoScreen), modelled on the existing screens.
  • Data comes from a new Platform_getProcessMaps(pid):
    • Linux: reads /proc/<pid>/maps.
    • Other platforms: stubbed (returns NULL) so the build stays green
      everywhere; the screen degrades gracefully to "Could not read process maps."
      rather than being hidden.
  • Documented in the in-app help screen and the man page (noted as Linux-only).

Testing

  • make distcheck with --enable-werror passes locally under gcc and clang.
  • Verified the screen opens with r, lists the mappings and refreshes.

Use of AI

Per CONTRIBUTING.md: the cross-platform stubs, the
help/man-page wording and the style cleanup were done with AI assistance
(acknowledged with a Co-authored-by: trailer on the commit). The feature and
the Linux implementation are my own work, and I have reviewed the whole change.

Note on CI

Any red *-clang / full-featured checks here are not from this change.
GitHub's ubuntu-latest has begun rolling to ubuntu-26.04, whose newer glibc
expands <string.h> string functions via _Generic and <math.h> isgreater*
via raw float comparisons — tripping htop's -Werror -Wfloat-equal and
-pedantic -std=c99 -Wc11-extensions in existing files (Macros.h,
XUtils.h, BacktraceScreen.c). None of the failures are in files this PR
touches, and unmodified main fails identically when built on ubuntu-26.04.

🤖 Generated with Claude Code

@coderabbitai

coderabbitai Bot commented Nov 5, 2026 •

Copy link
Copy Markdown

Explain Change →

Walkthrough

The change adds a process maps screen and binds it to the r key. The screen obtains map data through Platform_getProcessMaps, displays newline-delimited entries, and shows an error line if retrieval fails. Linux reads process maps from /proc; the other listed platform implementations return NULL.

Suggested reviewers: benbe

Change: Feature

Merge Risk: Moderate · up to fee00

After editing screens in PCP configurations, pressing r can abort htop instead of displaying process maps.

- [ ] Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Tip

🎯 Customize your risk assessments

Guide how CodeRabbit assesses merge risk and security architecture risk. Highlight sensitive changes and explain your security boundaries using Merge Risk Instructions and Security Risk Instructions in your review settings. Security architecture risk assessments require the Advanced plan or above.

✅ Automatic approvals, with your rules

Let CodeRabbit approve pull requests once required threads are resolved, pre-merge checks pass, and your risk limits are met. Enable Automatic approvals in review settings, with overrides for teams or file paths.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

The r key opens a view,
Maps arrive in lines anew.
Linux reads each process range,
Other platforms keep the same API exchange.
Sorted entries fill the screen,
Selection returns where it had been.

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 2

Review info

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Repository UI
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: 2929e130-34b1-4837-80c0-073765d9d833
Commits

Reviewing files that changed from the base of the PR and between 5091900 and 34cdc05.

Files selected for processing: 22

  • Action.c
  • Makefile.am
  • MapsScreen.c
  • MapsScreen.h
  • darwin/Platform.c
  • darwin/Platform.h
  • dragonflybsd/Platform.c
  • dragonflybsd/Platform.h
  • freebsd/Platform.c
  • freebsd/Platform.h
  • linux/Platform.c
  • linux/Platform.h
  • netbsd/Platform.c
  • netbsd/Platform.h
  • openbsd/Platform.c
  • openbsd/Platform.h
  • pcp/Platform.c
  • pcp/Platform.h
  • solaris/Platform.c
  • solaris/Platform.h
  • unsupported/Platform.c
  • unsupported/Platform.h

Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 7 remain after this review.

Comment thread linux/Platform.c Resolved
Comment thread MapsScreen.c Resolved
Adds a MapsScreen (InfoScreen) that displays /proc/<pid>/maps for the
highlighted process, bound to the 'r' key. Documented in the in-app help
screen and the man page.

The data is produced by a new Platform_getProcessMaps(); implemented on
Linux and stubbed (returns NULL) on all other platforms so the build
stays green everywhere.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Pierre Wilke <wilke.pierre@gmail.com>
@pwilke
pwilke marked this pull request as ready for review November 5, 2026 01:46
pwilke and others added 2 commits November 5, 2026 09:33
…ssMaps

fread() returns size_t and signals failure via ferror(), so the previous
'bytes < 0' check never ran and a read error was returned as success.
The trailing 'size += bytes' also double-counted the final chunk, padding
the buffer with uninitialised bytes.

Read in a single loop that grows the buffer as needed, accumulate the
size once, and check ferror() after the loop.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Pierre Wilke <wilke.pierre@gmail.com>
The lines were sorted with Vector_insertionSort, i.e. by ListItem's
strcmp on the whole text. Linux prints map start addresses with a
minimum of eight hex digits, so an 8-digit address sorts after a 9-digit
one and a higher mapping could be listed before a lower one.

/proc/<pid>/maps is already emitted in ascending start-address order, so
drop the sort and keep the kernel ordering.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Pierre Wilke <wilke.pierre@gmail.com>

@coderabbitai coderabbitai Bot 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.

Caution

Some comments are outside the diff and can’t be posted inline due to GitHub limitations.

⚠️ Outside diff range comments (1)

Major · Check the row class before the cast in actionShowMaps. · Action.c:950-954

Action.c:950-954
Major · Stability & Availability · Quick win

Check the row class before the cast in actionShowMaps.

After Screens setup, settings->ss can refer to a built-in screen while host->activeTable still refers to a dynamic table. The main panel then shows dynamic-table rows, which are Instance rows and not Process rows. Action_readableProcess checks only settings->ss->dynamic, so it passes. The cast then passes the non-Process row to the assert at Action.c:954. Assert-enabled builds abort. NDEBUG builds use a non-Process object as a Process, which is undefined behavior.

Trigger path in a PCP build:

  1. Make a dynamic screen active.
  2. Open Setup and select a built-in screen in the Screens list.
  3. Press F7, [, -, F8, ], +, or F9. rebuildSettingsArray sets settings->ss to the built-in screen. host->activeTable is not changed.
  4. Exit Setup and press r.
Suggested fix

-   Process *p = (Process *)Panel_getSelected((Panel *)st->mainPanel);
-   if (!p)
-      return HTOP_OK;
-
-   assert(Object_isA((const Object *)p, (const ObjectClass *)&Process_class));
+   Object *selected = Panel_getSelected((Panel *)st->mainPanel);
+   if (!selected || !Object_isA(selected, (const ObjectClass *)&Process_class))
+      return HTOP_OK;
+
+   Process *p = (Process *)selected;

This guard prevents the crash and undefined behavior in actionShowMaps only. It does not restore the pairing between settings->ss and host->activeTable. actionLsof and actionShowLocks use the same unchecked pattern and remain affected until the pairing is fixed in the Setup flow.

Review info

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Repository UI
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: 2b8d19a2-1060-41cb-beeb-11e2314dc175
Commits

Reviewing files that changed from the base of the PR and between a41277e and fee00b9.

Files selected for processing: 2

  • MapsScreen.c
  • linux/Platform.c

Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 7 remain after this review.

@pwilke

pwilke commented Nov 5, 2026

Copy link
Copy Markdown
Author

Good catch, but I'm unsure how to handle this.

  1. I follow coderabbitai's recommendation and fix the cast to Process* in actionShowMaps
  2. Fix it in actionShowMaps, actionLsof and actionShowLocks
  3. Open a later PR to fix all three there

I'd be in favor of the third option, but tell me what you prefer.

@BenBE

BenBE commented Nov 5, 2026

Copy link
Copy Markdown
Member

Option 3 sounds reasonable. What about option 4: Create a PR to fix it in those other places too, and just fix it in this PR as if it always was like this all along … ;-)

Apart from this general note, a quick nit: What about using v for (V)irtual Memory Map?

Also, returning the memory map as a char* doesn't look right for me. What about parsing it inside the Process_getProcessMemoryMap API and return a memory structure similar to what the file locks display does?

Actual code review work has to wait ATM.

@BenBE BenBE added Linux 🐧 Linux related issues feature request Completely new feature requested labels Nov 5, 2026
Comment thread linux/Platform.c
maps = xRealloc(maps, capacity);
}

size_t bytes = fread(maps + size, 1, capacity - size, fp);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The clang analyzer complains about this line, with EOF/error state not properly checked.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature request Completely new feature requested Linux 🐧 Linux related issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants