upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorbitflash-maintainer <noreply@bitflash.invalid>2026-09-02 16:36:42 +0000
committerbitflash-maintainer <noreply@bitflash.invalid>2026-09-02 16:36:42 +0000
commit123ae2e017d90fd18b291db3d76033781c1ead84 (patch)
tree691c494b9d19c28f9bc1ad7c128d8083c55a870c /src
parent2661de141e46dadfb2903bb12e72dc87c5a64375 (diff)
log: measure the debug log with a size type that can hold it
GetFilesize() returned int while ftell() returns long, so a debug.log of 2 GiB or more came back negative. Its only caller is the -maxdebugfilesize roll added in ae1c6a7, which skips the roll on a negative size: the rotation written for issue #34 would have switched itself off permanently at exactly the size it exists to prevent. Production was at 1.95 GiB growing 51-129 MB/day, about a day short of crossing 2 GiB. The same truncation capped the comparison at INT_MAX (2047.99 MB), so -maxdebugfilesize=2048 or higher could never be exceeded and disabled rotation outright. Both failures were silent. Widen the return to int64 and seek with ftello/fseeko (_ftelli64 and _fseeki64 on Windows). The roll in util.h is the function's only caller in the tree, so no other behaviour changes. A 32-bit off_t would reintroduce the same truncation, so its width is now a compile-time assertion rather than a silent runtime surprise.
Diffstat (limited to 'src')
-rw-r--r--src/util.cpp36
-rw-r--r--src/util.h6
2 files changed, 33 insertions, 9 deletions
diff --git a/src/util.cpp b/src/util.cpp
index a5a4e80..60142be 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -415,13 +415,37 @@ bool FileExists(const char* psz)
415#endif 415#endif
416} 416}
417 417
418int GetFilesize(FILE* file) 418#ifndef _WIN32
419// If off_t is 32 bits wide, ftello() truncates exactly like the int this
420// function used to return. Fail the build rather than ship the silent
421// version of the bug (32-bit hosts need -D_FILE_OFFSET_BITS=64).
422static_assert(sizeof(off_t) >= 8, "GetFilesize needs a 64-bit off_t");
423#endif
424
425// Returns the file's size in bytes, or -1 if it cannot be determined.
426//
427// This used to hold ftell()'s long in an int, so a file of 2 GiB or more came
428// back negative. Its only caller is the debug.log roll in util.h, which skips
429// the roll on a negative size -- i.e. rotation switched itself off for good at
430// exactly the size the roll exists to prevent, and any cap of 2048 MB or more
431// could never be exceeded at all. Both failures were silent.
432int64 GetFilesize(FILE* file)
419{ 433{
420 int nSavePos = ftell(file); 434#ifdef _WIN32
421 int nFilesize = -1; 435 __int64 nSavePos = _ftelli64(file);
422 if (fseek(file, 0, SEEK_END) == 0) 436 int64 nFilesize = -1;
423 nFilesize = ftell(file); 437 if (nSavePos >= 0 && _fseeki64(file, 0, SEEK_END) == 0)
424 fseek(file, nSavePos, SEEK_SET); 438 nFilesize = _ftelli64(file);
439 if (nSavePos >= 0)
440 _fseeki64(file, nSavePos, SEEK_SET);
441#else
442 off_t nSavePos = ftello(file);
443 int64 nFilesize = -1;
444 if (nSavePos >= 0 && fseeko(file, 0, SEEK_END) == 0)
445 nFilesize = ftello(file);
446 if (nSavePos >= 0)
447 fseeko(file, nSavePos, SEEK_SET);
448#endif
425 return nFilesize; 449 return nFilesize;
426} 450}
427 451
diff --git a/src/util.h b/src/util.h
index c47b8a7..89dce2f 100644
--- a/src/util.h
+++ b/src/util.h
@@ -154,7 +154,7 @@ void ParseString(const string& str, char c, vector<string>& v);
154string FormatMoney(int64 n, bool fPlus=false); 154string FormatMoney(int64 n, bool fPlus=false);
155bool ParseMoney(const char* pszIn, int64& nRet); 155bool ParseMoney(const char* pszIn, int64& nRet);
156bool FileExists(const char* psz); 156bool FileExists(const char* psz);
157int GetFilesize(FILE* file); 157int64 GetFilesize(FILE* file);
158uint64 GetRand(uint64 nMax); 158uint64 GetRand(uint64 nMax);
159int64 GetTime(); 159int64 GetTime();
160int64 GetAdjustedTime(); 160int64 GetAdjustedTime();
@@ -410,8 +410,8 @@ inline int OutputDebugStringF(const char* pszFormat, ...)
410 // so a rename is safe here: the next line simply reopens the 410 // so a rename is safe here: the next line simply reopens the
411 // path. One generation is kept as debug.log.old; logrotate 411 // path. One generation is kept as debug.log.old; logrotate
412 // (contrib/logrotate/) handles anything longer-term. 412 // (contrib/logrotate/) handles anything longer-term.
413 int nSize = GetFilesize(fileout); 413 int64 nSize = GetFilesize(fileout);
414 if (nSize >= 0 && (int64)nSize > nMaxDebugFileSize) 414 if (nSize >= 0 && nSize > nMaxDebugFileSize)
415 { 415 {
416 fclose(fileout); 416 fclose(fileout);
417 string strOldFile = strDebugFile + ".old"; 417 string strOldFile = strDebugFile + ".old";