Skip to content

Fix cpumeter segfault#2025

Open
fasterit wants to merge 3 commits into
htop-dev:mainfrom
fasterit:fix-cpumeter-segfault
Open

Fix cpumeter segfault#2025
fasterit wants to merge 3 commits into
htop-dev:mainfrom
fasterit:fix-cpumeter-segfault

Conversation

@fasterit

Copy link
Copy Markdown
Member

Fixes: #2024
and some int -> unsigned int mopping up old code (2nd commit)

Daniel Lange added 2 commits June 17, 2026 04:29
…rs array on CPU count change

When CPUs are hot-added while htop is running, LinuxMachine_scanCPUInfo
updates existingCPUs. The next Header_updateData call invokes
AllCPUsMeter_updateValues, which queries the new (larger) count from
AllCPUsMeter_getRange but accesses data->meters that was sized for the
old count hence causing an out-of-bounds access and SIGSEGV.

Changes:
- Rewriting CPUMeterCommonInit to detect count changes and resize
  data->meters (freeing excess meters when shrinking, reallocating and
  zero-filling when growing). data->cpus now stores the actual allocated
  meter count rather than existingCPUs.
- Having AllCPUsMeter_updateValues detect a count mismatch and call
  CPUMeterCommonInit before iterating over the meters array.
- Updating AllCPUsMeter_done to iterate over data->cpus (the number of
  meters actually allocated) instead of re-deriving via
  AllCPUsMeter_getRange, avoiding the same class of bug at teardown.
- Having CPUMeterCommonUpdateMode call CPUMeterCommonInit upfront for
  the same reason.

Fixes: htop-dev#2024

Assisted-by: Microsoft Copilot/Claude Sonnet 4.6
Assisted-by: Microsoft Copilot/Claude Sonnet 4.6
@coderabbitai

coderabbitai Bot commented Jun 17, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 6dd6082c-c292-4261-a847-f694967a28e7

📥 Commits

Reviewing files that changed from the base of the PR and between 6f86c5f and 73cf23c.

📒 Files selected for processing (1)
  • CPUMeter.c

📝 Walkthrough

Walkthrough

AllCPUsMeter_getRange now uses unsigned out-parameters. CPUMeterCommonInit reallocates the per-CPU meter array when the CPU count changes, and AllCPUsMeter_updateValues reinitializes on count mismatch before updating meters. AllCPUsMeter_done now iterates directly to data->cpus, and the multi-column and single-column CPU drawing paths use unsigned loop and range variables.

Assessment against linked issues

Objective Addressed Explanation
Fix segfault when vCPUs are added live (hot-plug) while htop is running [#2024]

Assessment against linked issues: Out-of-scope changes

No out-of-scope changes identified.

Poem

New CPUs arrived, and the array grew wide,
Unsigned steps kept every index aligned.
Reinit on change, no stale slots remain,
The crash stayed quiet; the meters stayed sane.
A smaller fix, with steadier lanes.


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

Comment @coderabbitai help to get the list of available commands.

@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: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 87ab446d-e4db-4308-9c1a-aa046c8dde8d

📥 Commits

Reviewing files that changed from the base of the PR and between e9518b3 and 6f86c5f.

📒 Files selected for processing (1)
  • CPUMeter.c

Comment thread CPUMeter.c
@BenBE BenBE added bug 🐛 Something isn't working code quality ♻️ Code quality enhancement labels Jun 17, 2026
@BenBE BenBE added this to the 3.6.0 milestone Jun 17, 2026
Comment thread CPUMeter.c Outdated
data->meters = xReallocArray(data->meters, (unsigned int)count, sizeof(Meter*));
/* zero-fill newly added entries */
if ((unsigned int)count > prevCount)
memset(data->meters + prevCount, 0, ((unsigned int)count - prevCount) * sizeof(Meter*));

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.

Consider using xReallocArrayZero.

Comment thread CPUMeter.c
assert(count >= 0);
unsigned int prevCount = data->cpus;
if ((unsigned int)count != prevCount) {
prevCount = data->cpus;

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.

The declaration of prevCount should be moved back here. There's no use of prevCount before this line.

Comment thread CPUMeter.c Outdated
int xpos = x + ((i / nrows) * colwidth) + d;
unsigned int nrows = (count + ncol - 1) / ncol;
for (unsigned int i = 0; i < count; i++) {
int col = i / nrows;

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.

There's an implicit cast from unsigned int to int here.

o Use xReallocArrayZero
o Fix more unsigned int casting
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug 🐛 Something isn't working code quality ♻️ Code quality enhancement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Segmentation fault in 3.4.1 after adding virtual CPUs

3 participants