Don't crash if SIGINT happens while printing an exception#384
Conversation
This wasn't handling Interrupted, since it's a subclass of BaseError, not Error. Since this is called from handleExceptions() while printing exceptions, the uncaught exception here was causing Nix to crash with a call to std::unexpected().
This hardens Nix against uncaught exceptions (like Interrupted) while printing exceptions.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughCentralized and hardened error logging in exception handlers and broadened an exception catch in source-path reading to return std::nullopt on any thrown exception (not just Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
📝 Coding Plan
Comment Tip CodeRabbit can use Trivy to scan for security misconfigurations and secrets in Infrastructure as Code files.Add a .trivyignore file to your project to customize which findings Trivy reports. |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/libmain/shared.cc`:
- Around line 350-356: The fallback logging lambda doLog currently calls
printError(...) inside its catch handler which itself can throw and therefore
must be guarded; update doLog (used by handleExceptions) so that the call to
printError is wrapped in its own try-catch that swallows any exception (or falls
back to a non-throwing fallback such as writing a raw message to stderr) to
ensure no exception escapes the catch block and unwinds out of handleExceptions;
reference symbols: doLog, logError, printError, handleExceptions.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 64ec2e94-8b32-4c4e-8b7b-85a1dd3d571d
📒 Files selected for processing (2)
src/libmain/shared.ccsrc/libutil/position.cc
| auto doLog = [&](BaseError & e) { | ||
| try { | ||
| logError(e.info()); | ||
| } catch (...) { | ||
| printError(ANSI_RED "error:" ANSI_NORMAL " Exception while printing an exception."); | ||
| } | ||
| }; |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# 1) Locate printError/logError declarations and implementations.
rg -nP --type=cpp --type=h -C3 '\b(printError|logError)\s*\('
# 2) Check whether printError is declared noexcept anywhere.
rg -nP --type=cpp --type=h '\bprintError\b[^{;]*\bnoexcept\b'
# 3) Inspect nearby bodies to confirm whether printError routes through logger paths.
rg -nP --type=cpp -C8 '\bprintError\s*\('Repository: DeterminateSystems/nix-src
Length of output: 42788
Guard the fallback logging path from rethrowing.
At line 354, the fallback calls printError(...) without an inner guard. Since printError can throw exceptions (see the comment in util.cc: "printError() also throws when remote is closed"), this path risks unwinding from within a catch block in handleExceptions(), which can cause program termination or undefined behavior.
Proposed hardening
- auto doLog = [&](BaseError & e) {
+ auto doLog = [&](BaseError & e) {
try {
logError(e.info());
} catch (...) {
- printError(ANSI_RED "error:" ANSI_NORMAL " Exception while printing an exception.");
+ static constexpr char msg[] = "error: Exception while printing an exception.\n";
+ try {
+ (void)!::write(STDERR_FILENO, msg, sizeof(msg) - 1);
+ } catch (...) {
+ // Never throw while handling exceptions.
+ }
}
};🧰 Tools
🪛 Cppcheck (2.20.0)
[error] 354-354: There is an unknown macro here somewhere. Configuration is required. If ANSI_NORMAL is a macro then please configure it.
(unknownMacro)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/libmain/shared.cc` around lines 350 - 356, The fallback logging lambda
doLog currently calls printError(...) inside its catch handler which itself can
throw and therefore must be guarded; update doLog (used by handleExceptions) so
that the call to printError is wrapped in its own try-catch that swallows any
exception (or falls back to a non-throwing fallback such as writing a raw
message to stderr) to ensure no exception escapes the catch block and unwinds
out of handleExceptions; reference symbols: doLog, logError, printError,
handleExceptions.
Motivation
This prevents crashes like
I.e. Ctrl-C is hit in
PosixSourceAccessor::readFile()while printing the Nix stack trace. This causes an unhandled exception inhandleExceptions()at top-level.Context
Summary by CodeRabbit