diff options
| author | bitflash-maintainer <noreply@bitflash.invalid> | 2026-09-02 16:42:39 +0000 |
|---|---|---|
| committer | bitflash-maintainer <noreply@bitflash.invalid> | 2026-09-02 16:42:39 +0000 |
| commit | 456b3b4a3372e7d13b764f41006bf2c15d92f46e (patch) | |
| tree | 25da7616af981f48625a931faeaaa9903fd519f0 /src/util.h | |
| parent | 123ae2e017d90fd18b291db3d76033781c1ead84 (diff) | |
log: stop a failed debug.log roll from repeating on every line
Neither remove() nor rename() was checked. When the rename fails -- a
read-only mount, permissions, EXDEV across a bind mount -- fopen() reopens
the same oversized file and writes the "grew past N MB" marker anyway. The
size never drops, so the next line takes the same branch, and every line
after that: the roll's own failure notice becomes unbounded growth, added
to the growth of issue #34 rather than replacing it.
Check rename(), and on failure latch the roll off for the rest of the run
after reporting it once -- on stderr as well as in the log, since whatever
blocked the rename may equally block the log write. An operator is told the
cap has stopped being enforced instead of learning it from the disk.
Diffstat (limited to 'src/util.h')
| -rw-r--r-- | src/util.h | 37 |
1 files changed, 31 insertions, 6 deletions
| @@ -399,8 +399,11 @@ inline int OutputDebugStringF(const char* pszFormat, ...) | |||
| 399 | else | 399 | else |
| 400 | strDebugFile = "debug.log"; | 400 | strDebugFile = "debug.log"; |
| 401 | } | 401 | } |
| 402 | // Latched by a failed rename in the roll below, which cannot be | ||
| 403 | // retried usefully and must not be retried endlessly. | ||
| 404 | static bool fRollDisabled = false; | ||
| 402 | FILE* fileout = fopen(strDebugFile.c_str(), "a"); | 405 | FILE* fileout = fopen(strDebugFile.c_str(), "a"); |
| 403 | if (fileout && nMaxDebugFileSize > 0) | 406 | if (fileout && nMaxDebugFileSize > 0 && !fRollDisabled) |
| 404 | { | 407 | { |
| 405 | // Roll an overgrown debug.log before adding to it. Nothing in the | 408 | // Roll an overgrown debug.log before adding to it. Nothing in the |
| 406 | // tree shrinks this file once the process is running (there is no | 409 | // tree shrinks this file once the process is running (there is no |
| @@ -416,12 +419,34 @@ inline int OutputDebugStringF(const char* pszFormat, ...) | |||
| 416 | fclose(fileout); | 419 | fclose(fileout); |
| 417 | string strOldFile = strDebugFile + ".old"; | 420 | string strOldFile = strDebugFile + ".old"; |
| 418 | remove(strOldFile.c_str()); // rename() won't clobber on Windows | 421 | remove(strOldFile.c_str()); // rename() won't clobber on Windows |
| 419 | rename(strDebugFile.c_str(), strOldFile.c_str()); | 422 | bool fRolled = (rename(strDebugFile.c_str(), strOldFile.c_str()) == 0); |
| 423 | int nRenameErrno = errno; // before fopen() can overwrite it | ||
| 420 | fileout = fopen(strDebugFile.c_str(), "a"); | 424 | fileout = fopen(strDebugFile.c_str(), "a"); |
| 421 | if (fileout) | 425 | if (fRolled) |
| 422 | fprintf(fileout, | 426 | { |
| 423 | "debug.log grew past %lld MB; previous contents moved to debug.log.old (-maxdebugfilesize)\n", | 427 | if (fileout) |
| 424 | (long long)(nMaxDebugFileSize / 1024 / 1024)); | 428 | fprintf(fileout, |
| 429 | "debug.log grew past %lld MB; previous contents moved to debug.log.old (-maxdebugfilesize)\n", | ||
| 430 | (long long)(nMaxDebugFileSize / 1024 / 1024)); | ||
| 431 | } | ||
| 432 | else | ||
| 433 | { | ||
| 434 | // The file is still over the cap, so this branch would be | ||
| 435 | // reached again on the next line and every line after it. | ||
| 436 | // Unlatched, the complaint about failing to roll becomes | ||
| 437 | // the runaway growth the roll exists to prevent. Say it | ||
| 438 | // once and stop trying -- on stderr too, because whatever | ||
| 439 | // blocked the rename (read-only mount, permissions, EXDEV | ||
| 440 | // across a bind mount) may equally block the log write. | ||
| 441 | fRollDisabled = true; | ||
| 442 | fprintf(stderr, | ||
| 443 | "cannot roll %s (rename to .old failed: %s); -maxdebugfilesize disabled for this run\n", | ||
| 444 | strDebugFile.c_str(), strerror(nRenameErrno)); | ||
| 445 | if (fileout) | ||
| 446 | fprintf(fileout, | ||
| 447 | "cannot roll debug.log (rename to .old failed: %s); -maxdebugfilesize disabled for this run\n", | ||
| 448 | strerror(nRenameErrno)); | ||
| 449 | } | ||
| 425 | } | 450 | } |
| 426 | } | 451 | } |
| 427 | if (fileout) | 452 | if (fileout) |