Skip to content

Show error message when trace feature fails on fork#2013

Open
re2zero wants to merge 1 commit into
htop-dev:mainfrom
re2zero:fix/issue-1991-trace-fork-error-feedback
Open

Show error message when trace feature fails on fork#2013
re2zero wants to merge 1 commit into
htop-dev:mainfrom
re2zero:fix/issue-1991-trace-fork-error-feedback

Conversation

@re2zero

@re2zero re2zero commented May 27, 2026

Copy link
Copy Markdown

Summary

  • Show error message in TraceScreen when TraceScreen_forkTracer() fails
  • Preserve errno across cleanup in error path to ensure accurate error reporting

Problem

When the trace feature (strace/truss) fails during the fork phase (e.g., out of memory, PID quota exceeded, seccomp/AppArmor restrictions), the TraceScreen was not displayed and users received no feedback. The UI appeared unresponsive even when pressing the s key multiple times.

Solution

  • Modified actionStrace() to always run the InfoScreen, adding an error message line when forkTracer fails
  • Modified TraceScreen_forkTracer() to preserve errno across cleanup operations for accurate error reporting

Changes

File Change
Action.c Show error message in TraceScreen when forkTracer fails
TraceScreen.c Preserve errno in error cleanup path

Test Plan

  • Build succeeds with ./autogen.sh && ./configure && make
  • make check passes
  • Manual test: Simulate fork failure (e.g., set ulimit -u 0 or use seccomp) and verify error message appears in TraceScreen

AI disclosure

Assisted-by: Claude (Anthropic)

Fixes #1991

@coderabbitai

coderabbitai Bot commented May 27, 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: 2ecd60e1-1824-4fa0-be74-94fca9fe7278

📥 Commits

Reviewing files that changed from the base of the PR and between 41e7977 and d66df1f.

📒 Files selected for processing (2)
  • Action.c
  • TraceScreen.c

📝 Walkthrough

Summary

Two small, focused changes fix issue #1991 so TraceScreen is shown and reports a failure when the tracer fork fails.

  • Action.c

    • Added #include <errno.h>.
    • actionStrace(): when TraceScreen_forkTracer() fails, errno is preserved and a one-line error (strerror(errno)) is appended to the TraceScreen/InfoScreen output. InfoScreen_run() is invoked unconditionally so the UI is shown even on fork failure. (≈ +7/−2)
  • TraceScreen.c

    • TraceScreen_forkTracer(): save/restore errno in the err: cleanup path so the original error reason is preserved after closing file descriptors.
    • TraceScreen_updateTrace(): initialize fd_strace to -1 and guard fileno/FD_ISSET calls on this->strace and a valid fd, avoiding assertions on NULL streams. (+12/−6)

Implementation quality

Clean, minimal, and idiomatic: preserves errno with the standard pattern, avoids clobbering errors during cleanup, and ensures the UI always presents immediate feedback. Changes are narrowly scoped, no public API changes, and follow conventional C error-handling. Commit split is logical and in-scope (UI/path handling in Action.c; error-preservation and robustness in TraceScreen.c).

Tests

Build and unit checks pass (./autogen.sh && ./configure && make; make check). Manual test guidance included (e.g., ulimit -u 0 or seccomp to simulate fork failure) to verify the visible error message.

Fixes #1991. Assisted-by: Claude (Anthropic).

Walkthrough

TraceScreen_forkTracer() now preserves errno during its error-cleanup. actionStrace includes <errno.h>, captures strerror(errno) on fork failure, appends that message to the TraceScreen/InfoScreen, and runs InfoScreen regardless of success. TraceScreen_updateTrace() now initializes fd_strace to -1, only calls fileno(this->strace) when non-NULL, and gates readiness/FD_ISSET checks on fd_strace >= 0 and this->strace_alive.

Assessment against linked issues

Objective Addressed Explanation
Display error message in TraceScreen when fork fails (#1991)
Preserve errno so error details are not lost (#1991)
Show TraceScreen even on startup failure (#1991)

Out-of-scope changes

Code Change Explanation
Validate fd_strace and gate FD_ISSET (TraceScreen.c:142-150,159) This change hardens stream readiness checks and is not required by #1991, which concerns UI feedback on fork failure.

Poem

When fork fails and echoes dim,
errno saved preserves the hymn.
A strerror line appears on screen,
so failures no longer go unseen.
Small fixes make the UX clean.

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 Infer (1.2.0)
TraceScreen.c

TraceScreen.c:8:10: fatal error: 'config.h' file not found
8 | #include "config.h" // IWYU pragma: keep
| ^~~~~~~~~~
1 error generated.
Error: the following clang command did not run successfully:
/opt/infer-linux-x86_64-v1.2.0/lib/infer/facebook-clang-plugins/clang/install/bin/clang-18
@/tmp/coderabbit-infer/d66df1f567c08bb1005b639250abc4d79c248fc6-e6d0ee0cb14fa6b3/tmp/clang_command_.tmp.8dbddb.txt
++Contents of '/tmp/coderabbit-infer/d66df1f567c08bb1005b639250abc4d79c248fc6-e6d0ee0cb14fa6b3/tmp/clang_command_.tmp.8dbddb.txt':
"-cc1" "-load"
"/opt/infer-linux-x86_64-v1.2.0/lib/infer/infer/bin/../../facebook-clang-plugins/libtooling/build/FacebookClangPlugin.dylib"
"-add-plugin" "BiniouASTExporter" "-plugin-arg-BiniouASTExporter" "-"
"-plugin-arg-BiniouASTExporter" "PREPEND_CURRENT_DIR=1"
"-plugin-arg-BiniouASTExporter" "MAX_STRING_SIZE=65535" "-cc1" "-triple"
"x86_64-unknown-linux-gnu" "-emit-obj" "-mrelax-all" "-disable-free"
"

... [truncated 689 characters] ...

"/opt/infer-linux-x86_64-v1.2.0/lib/infer/facebook-clang-plugins/clang/install/lib/clang/18/include"
"-internal-isystem" "/usr/local/include" "-internal-isystem"
"/usr/lib/gcc/x86_64-linux-gnu/12/../../../../x86_64-linux-gnu/include"
"-internal-externc-isystem" "/usr/include/x86_64-linux-gnu"
"-internal-externc-isystem" "/include" "-internal-externc-isystem"
"/usr/include" "-Wno-ignored-optimization-argument" "-Wno-everything"
"-ferror-limit" "19" "-fgnuc-version=4.2.1" "-fskip-odr-check-in-gmf"
"-D__GCC_HAVE_DWARF2_CFI_ASM=1" "-o"
"/tmp/coderabbit-infer/e6d0ee0cb14fa6b3/file.o" "-x" "c" "TraceScreen.c"
"-O0" "-fno-builtin" "-include"
"/opt/infer-linux-x86_64-v1.2.0/lib/infer/infer/bin/../lib/clang_wrappers/global_defines.h"
"-Wno-everything"
Action.c

Action.c:8:10: fatal error: 'config.h' file not found
8 | #include "config.h" // IWYU pragma: keep
| ^~~~~~~~~~
1 error generated.
Error: the following clang command did not run successfully:
/opt/infer-linux-x86_64-v1.2.0/lib/infer/facebook-clang-plugins/clang/install/bin/clang-18
@/tmp/coderabbit-infer/d66df1f567c08bb1005b639250abc4d79c248fc6-453eda0d3544c84e/tmp/clang_command_.tmp.7f8918.txt
++Contents of '/tmp/coderabbit-infer/d66df1f567c08bb1005b639250abc4d79c248fc6-453eda0d3544c84e/tmp/clang_command_.tmp.7f8918.txt':
"-cc1" "-load"
"/opt/infer-linux-x86_64-v1.2.0/lib/infer/infer/bin/../../facebook-clang-plugins/libtooling/build/FacebookClangPlugin.dylib"
"-add-plugin" "BiniouASTExporter" "-plugin-arg-BiniouASTExporter" "-"
"-plugin-arg-BiniouASTExporter" "PREPEND_CURRENT_DIR=1"
"-plugin-arg-BiniouASTExporter" "MAX_STRING_SIZE=65535" "-cc1" "-triple"
"x86_64-unknown-linux-gnu" "-emit-obj" "-mrelax-all" "-disable-free"
"-clea

... [truncated 670 characters] ...

tem"
"/opt/infer-linux-x86_64-v1.2.0/lib/infer/facebook-clang-plugins/clang/install/lib/clang/18/include"
"-internal-isystem" "/usr/local/include" "-internal-isystem"
"/usr/lib/gcc/x86_64-linux-gnu/12/../../../../x86_64-linux-gnu/include"
"-internal-externc-isystem" "/usr/include/x86_64-linux-gnu"
"-internal-externc-isystem" "/include" "-internal-externc-isystem"
"/usr/include" "-Wno-ignored-optimization-argument" "-Wno-everything"
"-ferror-limit" "19" "-fgnuc-version=4.2.1" "-fskip-odr-check-in-gmf"
"-D__GCC_HAVE_DWARF2_CFI_ASM=1" "-o"
"/tmp/coderabbit-infer/453eda0d3544c84e/file.o" "-x" "c" "Action.c" "-O0"
"-fno-builtin" "-include"
"/opt/infer-linux-x86_64-v1.2.0/lib/infer/infer/bin/../lib/clang_wrappers/global_defines.h"
"-Wno-everything"


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 and usage tips.

@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: 04edcd63-7a88-4372-bc36-3895a8c6313d

📥 Commits

Reviewing files that changed from the base of the PR and between ac2cdee and e87b8b7.

📒 Files selected for processing (2)
  • Action.c
  • TraceScreen.c

Comment thread Action.c
@BenBE BenBE added the enhancement Extension or improvement to existing feature label May 27, 2026
@re2zero re2zero marked this pull request as ready for review May 29, 2026 05:23
@Explorer09

Copy link
Copy Markdown
Contributor

In the second commit you accidentally deleted TraceScreen.c.

Comment thread TraceScreen.c Outdated
close(fdpair[1]);
close(fdpair[0]);
errno = saved_errno;
} while (0);

@Explorer09 Explorer09 May 30, 2026

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.

I think the do and while(0) keywords can be omitted here without violating the C99 spec. Just keep the { } braces for this code block.

I know the do and while(0) keywords would be necessary when defining the code block as a macro, or there are break statements inside the block that effectively serve as goto jumps.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Fixed in d66df1f — replaced do { ... } while(0) with plain { ... } braces since there are no break statements inside the block.

Comment thread Action.c Outdated
Comment thread TraceScreen.c
When TraceScreen_forkTracer() fails (e.g. OOM, PID quota exceeded,
seccomp/AppArmor restrictions), the TraceScreen was not displayed and
users received no feedback. The UI appeared unresponsive.

- Show error message in TraceScreen when forkTracer fails
- Preserve errno across cleanup in error path for accurate reporting
- Use plain snprintf (not xSnprintf) to avoid fail() on truncation
- Guard NULL strace before fileno() to prevent crash
- Guard all fd_strace usage with fd_strace >= 0 checks

Fixes htop-dev#1991

Assisted-by: Claude (Anthropic)
@re2zero re2zero force-pushed the fix/issue-1991-trace-fork-error-feedback branch from 41e7977 to d66df1f Compare June 3, 2026 08:33
@re2zero re2zero requested a review from BenBE June 11, 2026 06:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement Extension or improvement to existing feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

No UI feedback when trace feature fails on fork phase

3 participants