Skip to content

warnings bookkeeping: count warning codes instead of keeping the warnings - #10331

Open
ThomasWaldmann wants to merge 1 commit into
borgbackup:masterfrom
ThomasWaldmann:warnings-no-retain
Open

warnings bookkeeping: count warning codes instead of keeping the warnings#10331
ThomasWaldmann wants to merge 1 commit into
borgbackup:masterfrom
ThomasWaldmann:warnings-no-retain

Conversation

@ThomasWaldmann

Copy link
Copy Markdown
Member

What

add_warning() stored the message, its args and the formatting style of every warning emitted during a borg run in a global list, but all that is ever read back from it is the set of warning codes (get_ec() computes the final exit code from that).

For a BackupWarning, the args include the caught exception, and an exception references its traceback and thus the frames (with all their locals) of the code that failed. So every warning about a failed file kept e.g. the extract_item() frame - including the chunk data that was being written - alive for the rest of the run. On a full disk, every remaining file adds another chunk.

Measured with borg extract of 300 files of 2.5 MB whose writes all fail (ulimit -f, so each write gets EFBIG):

max RSS
master 876 MiB (300 exception objects and 555 MiB of chunk bytes kept alive via their frames)
this PR 416 MiB (same as a normal extraction of that archive)

How

  • keep only a Counter of warning codes; add_warning() takes just the code
  • init_ec_warnings() drops its never-used warnings parameter
  • get_ec() logs the per-code counts at debug level
  • print_warning() passes only the code

Tests

  • regression test at the print_warning_instance() level: the exception wrapped by the BackupWarning must be freed afterwards (checked via weakref). Fails on master, passes here.
  • unit test for the get_ec() warnings logic (one kind of warning, mixed kinds, error precedence, reset)

Note: 1.4-maint has the same bookkeeping in helpers/__init__.py, so the same fix applies there.

🤖 Generated with Claude Code

@codecov

codecov Bot commented Sep 6, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 87.75%. Comparing base (a6c45bc) to head (ff8b5ba).
⚠️ Report is 8 commits behind head on master.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@            Coverage Diff             @@
##           master   #10331      +/-   ##
==========================================
+ Coverage   87.72%   87.75%   +0.02%     
==========================================
  Files         103      103              
  Lines       18816    18810       -6     
  Branches     2904     2905       +1     
==========================================
- Hits        16507    16506       -1     
+ Misses       1605     1601       -4     
+ Partials      704      703       -1     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

…ings

add_warning() stored the message, its args and the formatting style of every
warning emitted during a borg run in a global list, but all that is ever read
back from it is the set of warning codes (get_ec() computes the final exit code
from that). For a BackupWarning, the args include the caught exception, and an
exception references its traceback and thus the frames (with all their locals)
of the code that failed - so every warning about a failed file kept e.g. the
extract_item frame including the chunk data that was being written alive for
the rest of the run. borg extract of 300 files of 2.5 MB whose writes all fail
peaked at 876 MiB RSS instead of 409 MiB, and on a full disk every remaining
file adds another chunk.

Keep only a Counter of warning codes: add_warning() takes just the code,
init_ec_warnings() loses its unused warnings list parameter, get_ec() logs the
per-code counts at debug level.

Add a regression test (the exception wrapped by a BackupWarning must be freed
after print_warning_instance()) and a unit test for the get_ec() warnings logic.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant