Skip to content

enforce 64‑bit off_t regardless of include order; prevent LTO type mismatch (Fixes #2938)#2943

Merged
zuiderkwast merged 3 commits into
valkey-io:unstablefrom
quanyeyang:fix/2938-off_t-include-order
Dec 21, 2025
Merged

enforce 64‑bit off_t regardless of include order; prevent LTO type mismatch (Fixes #2938)#2943
zuiderkwast merged 3 commits into
valkey-io:unstablefrom
quanyeyang:fix/2938-off_t-include-order

Conversation

@quanyeyang

@quanyeyang quanyeyang commented Dec 17, 2025

Copy link
Copy Markdown
Contributor

Fixes #2938

  • Root cause: On 32-bit builds, off_t depended on include order. lrulfu.c included <stdint.h>/<stdbool.h> via lrulfu.h before server.h, so _FILE_OFFSET_BITS=64 (from fmacros.h) was not in effect when glibc headers were first seen. This made off_t 32-bit in that TU, while 64-bit elsewhere, causing LTO linker “type mismatch” warnings and possible misoptimization.
  • Changes:
    1. Include fmacros.h first in src/lrulfu.h to ensure feature macros apply before any system header.
    2. Add a compile-time check in src/server.h:
    static_assert(sizeof(off_t) >= 8, "off_t must be 64-bit; ensure _FILE_OFFSET_BITS=64 is in effect before system headers");
    so we fail fast if include order regresses.
  • Why this works: fmacros.h defines _FILE_OFFSET_BITS 64 and related feature macros. Ensuring it is seen first gives a consistent 64-bit off_t across all TUs. The static_assert
    turns future include-order mistakes into early compile-time failures instead of link-time notes/warnings.
  • Testing:
    - Built on 32-bit Debian: no LTO type-mismatch at link, binaries produced successfully. Only GCC 11 ABI notes about _Atomic alignment (“note: … changed in GCC 11.1”), which are informational (-Wpsabi) and do not affect correctness.
  • Risk: very low; only header include order + a defensive assert. No runtime changes.
  • Address CI feedback: add fmacros.h to unit sources that include headers before server.h;

…t off_t to prevent LTO type mismatch (Fixes valkey-io#2938)

Signed-off-by: Ada-Church-Closure <2574094394@qq.com>
@zuiderkwast

Copy link
Copy Markdown
Contributor

Thank you!

It seems like we need fmacros.h in some more places in unit test files:

In file included from unit/test_entry.c:5:
unit/../server.h:61:23: error: static assertion failed: "off_t must be 64-bit; ensure _FILE_OFFSET_BITS=64 is in effect before system headers"
   61 | #define static_assert _Static_assert
      |                       ^~~~~~~~~~~~~~
unit/../server.h:93:1: note: in expansion of macro ‘static_assert’
   93 | static_assert(sizeof(off_t) >= 8, "off_t must be 64-bit; ensure _FILE_OFFSET_BITS=64 is in effect before system headers");
      | ^~~~~~~~~~~~~

(https://github.com/valkey-io/valkey/actions/runs/20293241116/job/58411398779?pr=2943#step:3:1337)

@codecov

codecov Bot commented Dec 18, 2025

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 73.84%. Comparing base (8ab0152) to head (62774f8).
⚠️ Report is 8 commits behind head on unstable.

Additional details and impacted files
@@             Coverage Diff              @@
##           unstable    #2943      +/-   ##
============================================
+ Coverage     72.28%   73.84%   +1.55%     
============================================
  Files           129      125       -4     
  Lines         70540    68898    -1642     
============================================
- Hits          50993    50879     -114     
+ Misses        19547    18019    -1528     
Files with missing lines Coverage Δ
src/server.h 100.00% <ø> (ø)

... and 35 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@quanyeyang

Copy link
Copy Markdown
Contributor Author

Thanks!I will handle this.

…); server: assert 64-bit off_t; unit:

        include fmacros early (Fixes valkey-io#2938)

Signed-off-by: Ada-Church-Closure <2574094394@qq.com>
@quanyeyang

Copy link
Copy Markdown
Contributor Author

I added fmacros.h at the top of headers that can be included standalone (entry/expire/lrulfu) and at the top of unit tests that include headers before server.h. Also reverted the sds.h change to avoid macro redefs in deps/libvalkey. The 32‑bitbuild should pass now; server.h keeps the static_assert as a guard against regressions.

Comment thread src/unit_output.txt Outdated
File seems to be added by mistake.

Signed-off-by: Viktor Söderqvist <viktor.soderqvist@est.tech>
@zuiderkwast zuiderkwast merged commit 4956506 into valkey-io:unstable Dec 21, 2025
52 checks passed
@quanyeyang quanyeyang deleted the fix/2938-off_t-include-order branch December 22, 2025 01:43
aradz44 pushed a commit to aradz44/valkey that referenced this pull request Dec 23, 2025
…smatch (valkey-io#2943)

Fixes valkey-io#2938
- Root cause: On 32-bit builds, off_t depended on include order.
lrulfu.c included <stdint.h>/<stdbool.h> via lrulfu.h before server.h,
so _FILE_OFFSET_BITS=64 (from fmacros.h) was not in effect when glibc
headers were first seen. This made off_t 32-bit in that TU, while 64-bit
elsewhere, causing LTO linker “type mismatch” warnings and possible
misoptimization.
- Changes:
1. Include fmacros.h first in src/lrulfu.h to ensure feature macros
apply before any system header.
          2. Add a compile-time check in src/server.h:
static_assert(sizeof(off_t) >= 8, "off_t must be 64-bit; ensure
_FILE_OFFSET_BITS=64 is in effect before system headers");
             so we fail fast if include order regresses.
- Why this works: fmacros.h defines _FILE_OFFSET_BITS 64 and related
feature macros. Ensuring it is seen first gives a consistent 64-bit
off_t across all TUs. The static_assert
turns future include-order mistakes into early compile-time failures
instead of link-time notes/warnings.
- Testing:
- Built on 32-bit Debian: no LTO type-mismatch at link, binaries
produced successfully. Only GCC 11 ABI notes about _Atomic alignment
(“note: … changed in GCC 11.1”), which are informational (-Wpsabi) and
do not affect correctness.
- Risk: very low; only header include order + a defensive assert. No
runtime changes.
- Address CI feedback: add fmacros.h to unit sources that include
headers before server.h;

---------

Signed-off-by: Ada-Church-Closure <2574094394@qq.com>
Signed-off-by: Viktor Söderqvist <viktor.soderqvist@est.tech>
Co-authored-by: Ada-Church-Closure <2574094394@qq.com>
Co-authored-by: Viktor Söderqvist <viktor.soderqvist@est.tech>
@zuiderkwast zuiderkwast linked an issue Dec 25, 2025 that may be closed by this pull request
@JimB123

JimB123 commented Jan 2, 2026

Copy link
Copy Markdown
Member

This solution seems brittle, and relies on including a file which wouldn't otherwise be needed in almost every .h file.

Would a better option be to use the -include compilation option to force the inclusion of fmacros.h in every compilation unit without having to explicitly define it?

@zuiderkwast

Copy link
Copy Markdown
Contributor

This solution seems brittle

With the static_assert, it doesn't seem too brittle to me, but without it I would agree.

Would a better option be to use the -include compilation option to force the inclusion of fmacros.h in every compilation unit without having to explicitly define it?

That's an interesting idea, but that may be brittle too. We have make and cmake files to maintain now and I know the two builds are already not identical. We could do both, i.e. explicit #includes and the -include option.

@JimB123

JimB123 commented Jan 6, 2026

Copy link
Copy Markdown
Member

The issue is that you should include what you use.

What we've done here is to include a file, which we don't use, because it has an indirect effect on something we use (or something used by something we use). This doesn't make any sense. Other than by trial and error, using the static assert, we don't know that we need this file.

Also - the message from the assert:

"off_t must be 64-bit; ensure _FILE_OFFSET_BITS=64 is in effect before system headers"

doesn't really help. This should say something like "ensure that fmacros.h is included before any system headers".

fmacros.h is used to define the environment for the code - and is not directly related to the code itself. That's why it makes more sense to include this from the build system.

Also of concern is that this "fix" is not applied universally or consistently. What we need is that for each compilation unit (.c file), we must include "fmacros.h" first. But instead, the PR applies a change in a small handful of .h files. Reordering of the .h files inside the .c file will break things. For example, if, in entry.c, we decide to include stdint.h before entry.h, the build is broken.

@zuiderkwast

zuiderkwast commented Jan 7, 2026

Copy link
Copy Markdown
Contributor

What matters most is to fix the failures as soon as possible. That's why I merged it quickly.

As for whether it's better to include fmacros.h explicitly or using a compiler command line flag, I think of little practical importance, as long as we have the static assert.

I wouldn't say the fmacros.h include file is unused. What it does is to define feature test macros, which need to be defined before including standard headers to affect some behavior, as documented in the man page feature_test_macros(7).

       NOTE: In order to be effective, a feature test macro must be
       defined before including any header files.  This can be done
       either in the compilation command (cc -DMACRO=value) or by
       defining the macro within the source code before including any
       headers.  The requirement that the macro must be defined before

IMO, if some .c or .h file relies on off_t being 64 bits, that file needs to define that macro. There's no need to do it for all files in the system, AFAICT.

It would have been enough to define only the specific macro (_FILE_OFFSET_BITS or _XOPEN_SOURCE to a value > 500 as explained in feature_test_macros(7)), instead of including fmacros.h.

For reference, I also found this in the man page for off_t(3type):

NOTES
       On some architectures, the width of off_t can be controlled with
       the feature test macro _FILE_OFFSET_BITS.

       The following headers also provide off_t: <aio.h>, <fcntl.h>,
       <stdio.h>, <sys/mman.h>, <sys/stat.h>, and <unistd.h>.

jdheyburn pushed a commit to jdheyburn/valkey that referenced this pull request Jan 8, 2026
…smatch (valkey-io#2943)

Fixes valkey-io#2938
- Root cause: On 32-bit builds, off_t depended on include order.
lrulfu.c included <stdint.h>/<stdbool.h> via lrulfu.h before server.h,
so _FILE_OFFSET_BITS=64 (from fmacros.h) was not in effect when glibc
headers were first seen. This made off_t 32-bit in that TU, while 64-bit
elsewhere, causing LTO linker “type mismatch” warnings and possible
misoptimization.
- Changes:
1. Include fmacros.h first in src/lrulfu.h to ensure feature macros
apply before any system header.
          2. Add a compile-time check in src/server.h:
static_assert(sizeof(off_t) >= 8, "off_t must be 64-bit; ensure
_FILE_OFFSET_BITS=64 is in effect before system headers");
             so we fail fast if include order regresses.
- Why this works: fmacros.h defines _FILE_OFFSET_BITS 64 and related
feature macros. Ensuring it is seen first gives a consistent 64-bit
off_t across all TUs. The static_assert
turns future include-order mistakes into early compile-time failures
instead of link-time notes/warnings.
- Testing:
- Built on 32-bit Debian: no LTO type-mismatch at link, binaries
produced successfully. Only GCC 11 ABI notes about _Atomic alignment
(“note: … changed in GCC 11.1”), which are informational (-Wpsabi) and
do not affect correctness.
- Risk: very low; only header include order + a defensive assert. No
runtime changes.
- Address CI feedback: add fmacros.h to unit sources that include
headers before server.h;

---------

Signed-off-by: Ada-Church-Closure <2574094394@qq.com>
Signed-off-by: Viktor Söderqvist <viktor.soderqvist@est.tech>
Co-authored-by: Ada-Church-Closure <2574094394@qq.com>
Co-authored-by: Viktor Söderqvist <viktor.soderqvist@est.tech>
hpatro pushed a commit to hpatro/valkey that referenced this pull request Mar 5, 2026
…smatch (valkey-io#2943)

Fixes valkey-io#2938
- Root cause: On 32-bit builds, off_t depended on include order.
lrulfu.c included <stdint.h>/<stdbool.h> via lrulfu.h before server.h,
so _FILE_OFFSET_BITS=64 (from fmacros.h) was not in effect when glibc
headers were first seen. This made off_t 32-bit in that TU, while 64-bit
elsewhere, causing LTO linker “type mismatch” warnings and possible
misoptimization.
- Changes:
1. Include fmacros.h first in src/lrulfu.h to ensure feature macros
apply before any system header.
          2. Add a compile-time check in src/server.h:
static_assert(sizeof(off_t) >= 8, "off_t must be 64-bit; ensure
_FILE_OFFSET_BITS=64 is in effect before system headers");
             so we fail fast if include order regresses.
- Why this works: fmacros.h defines _FILE_OFFSET_BITS 64 and related
feature macros. Ensuring it is seen first gives a consistent 64-bit
off_t across all TUs. The static_assert
turns future include-order mistakes into early compile-time failures
instead of link-time notes/warnings.
- Testing:
- Built on 32-bit Debian: no LTO type-mismatch at link, binaries
produced successfully. Only GCC 11 ABI notes about _Atomic alignment
(“note: … changed in GCC 11.1”), which are informational (-Wpsabi) and
do not affect correctness.
- Risk: very low; only header include order + a defensive assert. No
runtime changes.
- Address CI feedback: add fmacros.h to unit sources that include
headers before server.h;

---------

Signed-off-by: Ada-Church-Closure <2574094394@qq.com>
Signed-off-by: Viktor Söderqvist <viktor.soderqvist@est.tech>
Co-authored-by: Ada-Church-Closure <2574094394@qq.com>
Co-authored-by: Viktor Söderqvist <viktor.soderqvist@est.tech>
Signed-off-by: Harkrishn Patro <bunty.hari@gmail.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.

[BUG] Ignored linker warnings led to test failures [TEST-FAILURE] Test Failures in 32 Bit Daily Runs

4 participants