Skip to content

Fix SHM futex timeouts on 32-bit time64 libc - #17

Merged
ktsaou merged 3 commits into
mainfrom
fix/shm-futex-time64-abi
Sep 27, 2026
Merged

ktsaou merged 3 commits into
mainfrom
fix/shm-futex-time64-abi

Conversation

@ktsaou

@ktsaou ktsaou commented Sep 27, 2026 •

Copy link
Copy Markdown
Member

On 32-bit Linux with time64 libc, passing libc's timespec directly to the legacy futex syscall can turn a 100 ms SHM receive timeout into an immediate timeout. Idle session workers then repeatedly wake and consume CPU.

Marshal the selected kernel timeout ABI explicitly in C and Rust, retaining legacy-kernel compatibility and preserving infinite waits. Use portable Go timespec construction. Add elapsed-time and delayed-message regression tests, ARM ABI CI coverage, and integration guidance. Public APIs and the shared-memory wire layout are unchanged.

Validation:

  • Original C and Rust wrappers reproduced immediate expiry with ARM musl time64; corrected tests pass.
  • C passes native x86_64, i386 glibc time32/time64, and little-/big-endian ARM musl time64.
  • Rust passes 1.91.0 and latest stable 1.98.1, including ARM musl time32/time64 public-API tests.
  • Focused C/Rust/Go SHM and service tests and all nine language pairings pass.
  • Formatting, Clippy correctness/suspicious gates, workflow/shell validation and SOW audit pass.

Production CPU reduction has not been remeasured. Separate pre-existing Go UDS/Rust test 32-bit build gaps are tracked in SOW-0037.

Downstream vendor PR: netdata/netdata#24049.

Summary by CodeRabbit

  • Bug Fixes

    • Fixed shared-memory receive timeouts on Linux systems with differing 32-bit and time64 futex ABIs, helping waits honor their requested duration.
  • Documentation

    • Added guidance on timeout behavior and validating it across Linux ABI configurations.
    • Clarified that timeout validation does not establish production CPU usage or full cross-language platform support.

@qodo-free-for-open-source-projects

qodo-free-for-open-source-projects Bot commented Sep 27, 2026 •

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Action required

1. 32-bit RISC-V receive waits break 🐞 Bug ≡ Correctness
Description
futex_wait selects two 32-bit c_long fields for 32-bit RISC-V unless the libc is musl, even when
SYS_futex names the time64 syscall. On a 32-bit RISC-V time64-only target, that syscall reads a
16-byte timeout from an eight-byte array, so a finite receive can use an invalid or unintended
timeout.
Code

src/crates/netipc/src/transport/shm.rs[R1038-1041]

+    #[cfg(any(
+        target_arch = "x86_64",
+        all(target_arch = "riscv32", target_env = "musl")
+    ))]
Evidence
The changed condition gives i64 words only to riscv32 musl; other riscv32 targets receive
libc::c_long words, which are 32-bit there. The libc project describes RISC-V 32-bit as
time64-only and its plain syscall constants as aliases of the time64 variants. The changed code then
passes the resulting two-word array directly to libc::SYS_futex.

src/crates/netipc/src/transport/shm.rs[1034-1058]
src/crates/netipc/Cargo.lock[153-158]
🌐 The libc change identifies RISC-V 32-bit as time64-only and defines plain syscall constants as their time64 variants.: 🌐 The libc change identifies RISC-V 32-bit as time64-only and defines plain syscall constants as their time64 variants.: 🌐 The libc change identifies RISC-V 32-bit as time64-only and defines plain syscall constants as their time64 variants.: 🌐 The libc change identifies RISC-V 32-bit as time64-only and defines plain syscall constants as their time64 variants.: 🌐 The libc change identifies RISC-V 32-bit as time64-only and defines plain syscall constants as their time64 variants.: 🌐 The libc change identifies RISC-V 32-bit as time64-only and defines plain syscall constants as their time64 variants.: 🌐 The libc change identifies RISC-V 32-bit as time64-only and defines plain syscall constants as their time64 variants.: 🌐 The libc change identifies RISC-V 32-bit as time64-only and defines plain syscall constants as their time64 variants.

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The Rust timeout array uses 32-bit words on non-musl 32-bit RISC-V, although its futex syscall uses the time64 timeout layout.
## Fix Focus Areas
- src/crates/netipc/src/transport/shm.rs[1034-1053]
## Recommended Fix
Select two 64-bit timeout words for every RISC-V 32-bit target whose `SYS_futex` aliases the time64 syscall, rather than restricting that selection to musl. Add a target-specific check for the selected syscall and timeout layout.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. 32-bit RISC-V receive waits break ✗ Dismissed 🐞 Bug ≡ Correctness
Description
futex_wait selects two 32-bit c_long fields for 32-bit RISC-V unless the libc is musl, even when
SYS_futex names the time64 syscall. On a 32-bit RISC-V time64-only target, that syscall reads a
16-byte timeout from an eight-byte array, so a finite receive can use an invalid or unintended
timeout.
Code

src/crates/netipc/src/transport/shm.rs[R1038-1041]

+    #[cfg(any(
+        target_arch = "x86_64",
+        all(target_arch = "riscv32", target_env = "musl")
+    ))]
Evidence
The changed condition gives i64 words only to riscv32 musl; other riscv32 targets receive
libc::c_long words, which are 32-bit there. The libc project describes RISC-V 32-bit as
time64-only and its plain syscall constants as aliases of the time64 variants. The changed code then
passes the resulting two-word array directly to libc::SYS_futex.

src/crates/netipc/src/transport/shm.rs[1034-1058]
src/crates/netipc/Cargo.lock[153-158]
🌐 The libc change identifies RISC-V 32-bit as time64-only and defines plain syscall constants as their time64 variants.: 🌐 The libc change identifies RISC-V 32-bit as time64-only and defines plain syscall constants as their time64 variants.: 🌐 The libc change identifies RISC-V 32-bit as time64-only and defines plain syscall constants as their time64 variants.: 🌐 The libc change identifies RISC-V 32-bit as time64-only and defines plain syscall constants as their time64 variants.

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The Rust timeout array uses 32-bit words on non-musl 32-bit RISC-V, although its futex syscall uses the time64 timeout layout.
## Fix Focus Areas
- src/crates/netipc/src/transport/shm.rs[1034-1053]
## Recommended Fix
Select two 64-bit timeout words for every RISC-V 32-bit target whose `SYS_futex` aliases the time64 syscall, rather than restricting that selection to musl. Add a target-specific check for the selected syscall and timeout layout.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. 32-bit RISC-V receive waits break ✗ Dismissed 🐞 Bug ≡ Correctness
Description
futex_wait selects two 32-bit c_long fields for 32-bit RISC-V unless the libc is musl, even when
SYS_futex names the time64 syscall. On a 32-bit RISC-V time64-only target, that syscall reads a
16-byte timeout from an eight-byte array, so a finite receive can use an invalid or unintended
timeout.
Code

src/crates/netipc/src/transport/shm.rs[R1038-1041]

+    #[cfg(any(
+        target_arch = "x86_64",
+        all(target_arch = "riscv32", target_env = "musl")
+    ))]
Evidence
The changed condition gives i64 words only to riscv32 musl; other riscv32 targets receive
libc::c_long words, which are 32-bit there. The libc project describes RISC-V 32-bit as
time64-only and its plain syscall constants as aliases of the time64 variants. The changed code then
passes the resulting two-word array directly to libc::SYS_futex.

src/crates/netipc/src/transport/shm.rs[1034-1058]
src/crates/netipc/Cargo.lock[153-158]
🌐 The libc change identifies RISC-V 32-bit as time64-only and defines plain syscall constants as their time64 variants.: 🌐 The libc change identifies RISC-V 32-bit as time64-only and defines plain syscall constants as their time64 variants.

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The Rust timeout array uses 32-bit words on non-musl 32-bit RISC-V, although its futex syscall uses the time64 timeout layout.
## Fix Focus Areas
- src/crates/netipc/src/transport/shm.rs[1034-1053]
## Recommended Fix
Select two 64-bit timeout words for every RISC-V 32-bit target whose `SYS_futex` aliases the time64 syscall, rather than restricting that selection to musl. Add a target-specific check for the selected syscall and timeout layout.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

4. Rust timeout tests miss time64 ✓ Resolved 🐞 Bug ☼ Reliability
Description
run-rust-shm-timeout-abi.sh varies the libc configuration, but shm_timeout_abi only prints ABI
sizes and never asserts which layout was compiled. If the configuration is ignored or selects the
wrong layout, both invocations can pass their timeout checks while exercising the same ABI instead
of establishing legacy and time64 coverage.
Code

tests/run-rust-shm-timeout-abi.sh[R14-16]

+    RUST_LIBC_UNSTABLE_MUSL_V1_2_3=$time64 cargo test \
+        --manifest-path "$root/src/crates/netipc/Cargo.toml" \
+        --target arm-unknown-linux-musleabihf --test shm_timeout -- --nocapture
Evidence
The script distinguishes its two runs by setting the libc configuration to 0 and 1, but the
fixture prints ABI sizes and asserts only elapsed time. Because neither invocation checks the
compiled layout, passing results establish timeout behavior for the ABI actually selected, not that
both intended layouts were exercised.

tests/run-rust-shm-timeout-abi.sh[13-17]
src/crates/netipc/tests/shm_timeout.rs[13-26]
docs/level1-posix-shm.md[357-362]
tests/run-rust-shm-timeout-abi.sh[12-17]
src/crates/netipc/tests/shm_timeout.rs[14-26]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The Rust ABI regression runs with two libc configuration values but does not fail if either invocation compiles the wrong layout. Make each invocation verify its expected 32-bit legacy or time64 representation.
## Fix Focus Areas
- tests/run-rust-shm-timeout-abi.sh[12-17]
- src/crates/netipc/tests/shm_timeout.rs[13-20]
## Recommended Fix
Pass the expected layout from the script to each test invocation. In the fixture, assert 32-bit pointer width and the expected `time_t`/`timespec` layout, including `tv_sec` size, before the timeout checks. Keep the diagnostic output, but fail the test when the compiled layout differs from the expected one.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


5. Rust timeout tests miss time64 ✓ Resolved 🐞 Bug ☼ Reliability
Description
run-rust-shm-timeout-abi.sh varies the libc configuration, but shm_timeout_abi only prints ABI
sizes and never asserts which layout was compiled. If the configuration is ignored or selects the
wrong layout, both invocations can pass their timeout checks while exercising the same ABI instead
of establishing legacy and time64 coverage.
Code

tests/run-rust-shm-timeout-abi.sh[R14-16]

+    RUST_LIBC_UNSTABLE_MUSL_V1_2_3=$time64 cargo test \
+        --manifest-path "$root/src/crates/netipc/Cargo.toml" \
+        --target arm-unknown-linux-musleabihf --test shm_timeout -- --nocapture
Evidence
The script distinguishes its two runs by setting the libc configuration to 0 and 1, but the
fixture prints ABI sizes and asserts only elapsed time. Because neither invocation checks the
compiled layout, passing results establish timeout behavior for the ABI actually selected, not that
both intended layouts were exercised.

tests/run-rust-shm-timeout-abi.sh[13-17]
src/crates/netipc/tests/shm_timeout.rs[13-26]
docs/level1-posix-shm.md[357-362]
tests/run-rust-shm-timeout-abi.sh[12-17]
src/crates/netipc/tests/shm_timeout.rs[14-26]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The Rust ABI regression runs with two libc configuration values but does not fail if either invocation compiles the wrong layout. Make each invocation verify its expected 32-bit legacy or time64 representation.
## Fix Focus Areas
- tests/run-rust-shm-timeout-abi.sh[12-17]
- src/crates/netipc/tests/shm_timeout.rs[13-20]
## Recommended Fix
Pass the expected layout from the script to each test invocation. In the fixture, assert 32-bit pointer width and the expected `time_t`/`timespec` layout, including `tv_sec` size, before the timeout checks. Keep the diagnostic output, but fail the test when the compiled layout differs from the expected one.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


6. Rust timeout tests miss time64 ✓ Resolved 🐞 Bug ☼ Reliability
Description
run-rust-shm-timeout-abi.sh varies the libc configuration, but shm_timeout_abi only prints ABI
sizes and never asserts which layout was compiled. If the configuration is ignored or selects the
wrong layout, both invocations can pass their timeout checks while exercising the same ABI instead
of establishing legacy and time64 coverage.
Code

tests/run-rust-shm-timeout-abi.sh[R14-16]

+    RUST_LIBC_UNSTABLE_MUSL_V1_2_3=$time64 cargo test \
+        --manifest-path "$root/src/crates/netipc/Cargo.toml" \
+        --target arm-unknown-linux-musleabihf --test shm_timeout -- --nocapture
Evidence
The script distinguishes its two runs by setting the libc configuration to 0 and 1, but the
fixture prints ABI sizes and asserts only elapsed time. Because neither invocation checks the
compiled layout, passing results establish timeout behavior for the ABI actually selected, not that
both intended layouts were exercised.

tests/run-rust-shm-timeout-abi.sh[13-17]
src/crates/netipc/tests/shm_timeout.rs[13-26]
docs/level1-posix-shm.md[357-362]
tests/run-rust-shm-timeout-abi.sh[12-17]
src/crates/netipc/tests/shm_timeout.rs[14-26]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The Rust ABI regression runs with two libc configuration values but does not fail if either invocation compiles the wrong layout. Make each invocation verify its expected 32-bit legacy or time64 representation.
## Fix Focus Areas
- tests/run-rust-shm-timeout-abi.sh[12-17]
- src/crates/netipc/tests/shm_timeout.rs[13-20]
## Recommended Fix
Pass the expected layout from the script to each test invocation. In the fixture, assert 32-bit pointer width and the expected `time_t`/`timespec` layout, including `tv_sec` size, before the timeout checks. Keep the diagnostic output, but fail the test when the compiled layout differs from the expected one.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Tip of the day
💡 Did you know, you can describe a rule in plain language on the Rules page and Qodo drafts it for you

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

@coderabbitai

coderabbitai Bot commented Sep 27, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: b9ee1423-9b7a-4df2-8fcc-734221d5b9a6

📥 Commits

Reviewing files that changed from the base of the PR and between 0d17a9d and 6aa8201.

📒 Files selected for processing (17)
  • .agents/sow/done/SOW-0036-20260927-shm-futex-time64-abi.md
  • .agents/sow/done/SOW-0038-20260927-publish-vendor-shm-time64.md
  • .agents/sow/done/SOW-0039-20260927-rust-timeout-abi-assertions.md
  • .agents/sow/pending/SOW-0037-20260927-linux-32-bit-build-coverage.md
  • .github/workflows/runtime-safety.yml
  • CMakeLists.txt
  • bench/drivers/rust/src/main.rs
  • docs/level1-posix-shm.md
  • docs/netipc-integrator-skill.md
  • src/crates/netipc/src/transport/shm.rs
  • src/crates/netipc/src/transport/shm_tests.rs
  • src/crates/netipc/tests/shm_timeout.rs
  • src/go/pkg/netipc/transport/posix/shm_linux.go
  • src/libnetdata/netipc/src/transport/posix/netipc_shm.c
  • tests/fixtures/c/test_shm_timeout.c
  • tests/run-rust-shm-timeout-abi.sh
  • tests/run-shm-timeout-abi.sh

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

C and Rust shared-memory futex waits now marshal timeout values for the selected Linux syscall ABI. Go uses syscall.NsecToTimespec. Regression tests and ARM ABI checks cover timeout durations, wakeups, and ABI layouts. Documentation and SOW records describe validation, delivery, and separate 32-bit build gaps.

Changes

SHM Futex Timeout ABI

Layer / File(s) Summary
Timeout ABI selection and marshalling
.agents/sow/done/SOW-0036-20260927-shm-futex-time64-abi.md, src/libnetdata/netipc/src/transport/posix/netipc_shm.c, src/crates/netipc/src/transport/shm.rs, src/go/pkg/netipc/transport/posix/shm_linux.go, bench/drivers/rust/src/main.rs, docs/level1-posix-shm.md
C selects the futex syscall and marshals timeout fields to its kernel ABI. Rust passes two kernel time words to SYS_futex. Go constructs the remaining timeout with syscall.NsecToTimespec. Documentation describes the timeout layouts and zero-timeout behavior.
Timeout regression tests and ABI validation
tests/fixtures/c/test_shm_timeout.c, tests/run-shm-timeout-abi.sh, tests/run-rust-shm-timeout-abi.sh, src/crates/netipc/tests/shm_timeout.rs, src/crates/netipc/src/transport/shm_tests.rs, CMakeLists.txt, .github/workflows/runtime-safety.yml, docs/level1-posix-shm.md, docs/netipc-integrator-skill.md, .agents/sow/done/SOW-0036-20260927-shm-futex-time64-abi.md, .agents/sow/done/SOW-0039-20260927-rust-timeout-abi-assertions.md
C and Rust tests check timeout results, elapsed time, and delayed-message receipt. The runners and workflow check C and Rust ABI layouts under ARM emulation. Documentation and SOWs record the checks and validation outcomes.
Source publication and downstream vendoring record
.agents/sow/done/SOW-0038-20260927-publish-vendor-shm-time64.md
The SOW records source preflight results, publication and vendoring evidence, validation outcomes, and the status of both pull requests.

Linux 32-bit Build Tracking

Layer / File(s) Summary
Pending 32-bit build investigation
.agents/sow/pending/SOW-0037-20260927-linux-32-bit-build-coverage.md
The SOW tracks Go 386 and ARM musl Rust build and test gaps. It leaves the target matrix and UDS syscall strategy unresolved, with implementation pending investigation.

Priority: ➖ Normal

Estimated code review effort: 3 (Moderate) | ~25 minutes

Change: Bug fix

Merge Risk: ⚪ Minimal · up to 6aa82

No confirmed regression remains to block merging. Target-specific C ABI validation remains prudent during normal release checks.

Security Architecture Review

Security architecture risk: 🔵 Low · up to 6aa82

The change appears to repair timeout behavior without expanding the shared-memory API or weakening message checks. Some platform-specific behavior and the production CPU effect remain unverified.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • inferred — A timeout ABI error can affect receive-worker availability on affected Linux builds. The inspected change does not establish a new caller or a larger shared-memory trust boundary.

Security Findings and Attack Paths

  • inferred — No introduced path from peer-controlled shared-memory fields to the syscall number or timeout pointer, or bypass of the inspected message bounds, was established. This is limited to the inspected paths, not a finding of complete security coverage.

Trust Boundaries and Controls

  • observed — The transport owns the libc-to-kernel timeout conversion. Receive continues to gate copying on sequence observation and the caller-buffer and shared-area capacity limits.

Resilience and Maintainability Implications

  • observed — Finite waits retain a monotonic deadline across retries, while infinite waits pass a null futex timeout. These paths contain interruption and spurious-wakeup effects without changing message ownership.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 23.08% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 13 functions across 9 files. (8 skipped: … Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely identifies the main change: fixing shared-memory futex timeouts on 32-bit systems using time64 libc.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

Docstring coverage is 23.08% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 13 functions across 9 files. (8 skipped: 8 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@qodo-free-for-open-source-projects

qodo-free-for-open-source-projects Bot commented Sep 27, 2026 •

Copy link
Copy Markdown

PR Summary by Qodo

Fix SHM futex timeouts on 32-bit time64 libc

🐞 Bug fix 🧪 Tests 📝 Documentation ⚙️ Configuration changes 🕐 40+ Minutes

Grey Divider

AI Description

• Marshal C and Rust futex timeouts correctly to prevent premature SHM expiry on 32-bit time64 libc.
• Construct Go timeouts portably while preserving legacy-kernel compatibility and infinite waits.
• Add cross-ABI blocking and wakeup tests, ARM CI coverage, and integrator guidance.
Diagram

graph TD
  Receive["SHM receive"] --> Budget["Remaining budget"] --> Finite{"Finite timeout?"}
  Finite -->|yes| Convert["Timeout conversion"] --> Futex["Kernel futex"] --> Result["Wake or timeout"]
  Finite -->|no: null pointer| Futex
  Peer["Peer sender"] -->|wake| Futex
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Use futex_time64 for time64 libc
  • ➕ Matches the wider timeout ABI on supported targets.
  • ➕ Avoids relying on the legacy syscall's seconds range.
  • ➖ Would require newer kernel support solely because libc uses time64.
  • ➖ Still requires careful kernel-layout handling, and all supported relative budgets already fit the legacy range.

Recommendation: Keep the PR's explicit syscall-ABI marshalling. The supported timeout range fits legacy futex seconds, so selecting futex_time64 based on libc alone would sacrifice older-kernel compatibility without fixing a needed range limitation.

Files changed (15) +733 / -30

Bug fix (4) +51 / -28
main.rsInitialize benchmark clock timespec portably +1/-4

Initialize benchmark clock timespec portably

• Uses Default initialization so the clock helper compiles when libc's timespec includes private time64 padding. Benchmark behavior is unchanged.

bench/drivers/rust/src/main.rs

shm.rsMarshal Rust futex timeouts into kernel words +29/-17

Marshal Rust futex timeouts into kernel words

• Converts libc timespec values to the selected syscall's two-word layout while retaining null pointers for infinite waits. Uses Default initialization where time64 libc timespec has private padding.

src/crates/netipc/src/transport/shm.rs

shm_linux.goConstruct Go futex durations portably +2/-4

Construct Go futex durations portably

• Replaces fixed-width Timespec field assignments with syscall.NsecToTimespec for architecture-correct relative timeout construction.

src/go/pkg/netipc/transport/posix/shm_linux.go

netipc_shm.cMarshal C futex timeouts for the selected syscall +19/-3

Marshal C futex timeouts for the selected syscall

• Passes explicit kernel-sized seconds and nanoseconds instead of a libc timespec pointer. Selects the available futex syscall ABI and preserves null-pointer infinite waits.

src/libnetdata/netipc/src/transport/posix/netipc_shm.c

Tests (6) +198 / -2
CMakeLists.txtRegister the C timeout regression +5/-0

Register the C timeout regression

• Builds the public SHM timeout fixture and runs it through CTest with a bounded test timeout.

CMakeLists.txt

shm_tests.rsAssert that Rust receives actually wait +12/-2

Assert that Rust receives actually wait

• Extends the timeout test to check elapsed time for 100 ms and 1100 ms empty receives, catching immediate expiry and lost subsecond durations.

src/crates/netipc/src/transport/shm_tests.rs

shm_timeout.rsTest Rust public-API waits and peer wakeups +42/-0

Test Rust public-API waits and peer wakeups

• Adds an integration fixture for elapsed finite waits and delayed messages during finite, infinite, and maximum-duration receives.

src/crates/netipc/tests/shm_timeout.rs

test_shm_timeout.cExercise C timeout duration and wake behavior +99/-0

Exercise C timeout duration and wake behavior

• Tests elapsed and CPU time for empty receives and delayed-peer wakeups across finite, infinite, and maximum API timeouts. Can require a 32-bit time64 libc at compile time.

tests/fixtures/c/test_shm_timeout.c

run-rust-shm-timeout-abi.shRun Rust timeout fixtures on ARM musl +17/-0

Run Rust timeout fixtures on ARM musl

• Cross-builds and executes the public-API regression under QEMU with both libc crate musl time layouts.

tests/run-rust-shm-timeout-abi.sh

run-shm-timeout-abi.shRun C timeout fixtures across compiler ABIs +23/-0

Run C timeout fixtures across compiler ABIs

• Compiles the production C SHM transport and timeout fixture with caller-supplied compiler flags, then runs it natively or through a configured emulator.

tests/run-shm-timeout-abi.sh

Documentation (4) +459 / -0
SOW-0036-20260927-shm-futex-time64-abi.mdRecord the completed timeout ABI repair +281/-0

Record the completed timeout ABI repair

• Documents the root cause, ABI choice, validation matrix, limitations, and follow-up work. Distinguishes local blocking evidence from unmeasured production CPU impact.

.agents/sow/done/SOW-0036-20260927-shm-futex-time64-abi.md

SOW-0037-20260927-linux-32-bit-build-coverage.mdTrack separate 32-bit build gaps +128/-0

Track separate 32-bit build gaps

• Records existing Go UDS and Rust test compilation failures as a pending platform-coverage task rather than expanding the timeout repair.

.agents/sow/pending/SOW-0037-20260927-linux-32-bit-build-coverage.md

level1-posix-shm.mdDocument futex ABI requirements and validation +41/-0

Document futex ABI requirements and validation

• Explains kernel-versus-libc timeout layouts, legacy compatibility, and infinite waits. Provides C and Rust cross-ABI regression commands and states the limits of emulated testing.

docs/level1-posix-shm.md

netipc-integrator-skill.mdGuide 32-bit integrators through timeout checks +9/-0

Guide 32-bit integrators through timeout checks

• Directs integrators to validate elapsed waits and delayed-peer wakeups on their target libc, without treating the fixture as full platform or production CPU validation.

docs/netipc-integrator-skill.md

Other (1) +25 / -0
runtime-safety.ymlAdd ARM timeout ABI CI coverage +25/-0

Add ARM timeout ABI CI coverage

• Adds an emulated ARM job for C glibc time32/time64 and Rust musl legacy/time64 timeout fixtures.

.github/workflows/runtime-safety.yml

@codacy-production

codacy-production Bot commented Sep 27, 2026 •

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 4 complexity · 18 duplication

Metric Results
Complexity 4
Duplication 18

View in Codacy

🟢 Coverage 100.00% diff coverage · +0.02% coverage variation

Metric Results
Coverage variation ✅ +0.02% coverage variation (-1.00%)
Diff coverage ✅ 100.00% diff coverage

View coverage diff in Codacy

Coverage variation details
Coverable lines Covered lines Coverage
Common ancestor commit (0d17a9d) Report Missing Report Missing Report Missing
Head commit (6aa8201) 16336 (-3) 14801 (+1) 90.60% (+0.02%)

Coverage variation is the difference between the coverage for the head and common ancestor commits of the pull request branch: <coverage of head commit> - <coverage of common ancestor commit>

Diff coverage details
Coverable lines Covered lines Diff coverage
Pull request (#17) 18 18 100.00%

Diff coverage is the percentage of lines that are covered by tests out of the coverable lines that the pull request added or modified: <covered lines added or modified>/<coverable lines added or modified> * 100%

1 Codacy didn't receive coverage data for the commit, or there was an error processing the received data. Check your integration for errors and validate that your coverage setup is correct.

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

@qodo-code-review

qodo-code-review Bot commented Sep 27, 2026 •

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Action required

1. 32-bit RISC-V receive waits break ✗ Dismissed 🐞 Bug ≡ Correctness
Description
futex_wait selects two 32-bit c_long fields for 32-bit RISC-V unless the libc is musl, even when
SYS_futex names the time64 syscall. On a 32-bit RISC-V time64-only target, that syscall reads a
16-byte timeout from an eight-byte array, so a finite receive can use an invalid or unintended
timeout.
Code

src/crates/netipc/src/transport/shm.rs[R1038-1041]

+    #[cfg(any(
+        target_arch = "x86_64",
+        all(target_arch = "riscv32", target_env = "musl")
+    ))]
Evidence
The changed condition gives i64 words only to riscv32 musl; other riscv32 targets receive
libc::c_long words, which are 32-bit there. The libc project describes RISC-V 32-bit as
time64-only and its plain syscall constants as aliases of the time64 variants. The changed code then
passes the resulting two-word array directly to libc::SYS_futex.

src/crates/netipc/src/transport/shm.rs[1034-1058]
src/crates/netipc/Cargo.lock[153-158]
🌐 The libc change identifies RISC-V 32-bit as time64-only and defines plain syscall constants as their time64 variants.

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The Rust timeout array uses 32-bit words on non-musl 32-bit RISC-V, although its futex syscall uses the time64 timeout layout.

## Fix Focus Areas
- src/crates/netipc/src/transport/shm.rs[1034-1053]

## Recommended Fix
Select two 64-bit timeout words for every RISC-V 32-bit target whose `SYS_futex` aliases the time64 syscall, rather than restricting that selection to musl. Add a target-specific check for the selected syscall and timeout layout.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

2. Rust timeout tests miss time64 ✓ Resolved 🐞 Bug ☼ Reliability
Description
run-rust-shm-timeout-abi.sh varies the libc configuration, but shm_timeout_abi only prints ABI
sizes and never asserts which layout was compiled. If the configuration is ignored or selects the
wrong layout, both invocations can pass their timeout checks while exercising the same ABI instead
of establishing legacy and time64 coverage.
Code

tests/run-rust-shm-timeout-abi.sh[R14-16]

+    RUST_LIBC_UNSTABLE_MUSL_V1_2_3=$time64 cargo test \
+        --manifest-path "$root/src/crates/netipc/Cargo.toml" \
+        --target arm-unknown-linux-musleabihf --test shm_timeout -- --nocapture
Evidence
The script distinguishes its two runs by setting the libc configuration to 0 and 1, but the
fixture prints ABI sizes and asserts only elapsed time. Because neither invocation checks the
compiled layout, passing results establish timeout behavior for the ABI actually selected, not that
both intended layouts were exercised.

tests/run-rust-shm-timeout-abi.sh[13-17]
src/crates/netipc/tests/shm_timeout.rs[13-26]
docs/level1-posix-shm.md[357-362]
tests/run-rust-shm-timeout-abi.sh[12-17]
src/crates/netipc/tests/shm_timeout.rs[14-26]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The Rust ABI regression runs with two libc configuration values but does not fail if either invocation compiles the wrong layout. Make each invocation verify its expected 32-bit legacy or time64 representation.

## Fix Focus Areas
- tests/run-rust-shm-timeout-abi.sh[12-17]
- src/crates/netipc/tests/shm_timeout.rs[13-20]

## Recommended Fix
Pass the expected layout from the script to each test invocation. In the fixture, assert 32-bit pointer width and the expected `time_t`/`timespec` layout, including `tv_sec` size, before the timeout checks. Keep the diagnostic output, but fail the test when the compiled layout differs from the expected one.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Context sources
✅ Web pages:
  +20 more
✅ Cross-repo context — repo relationships
  Explored: repo: netdata/netdata (sha: 4464a9ed) — View relationship
Review mode: 🧠 Deep: This is a security-adjacent systems portability fix with substantial C/Rust/Go runtime logic, ABI selection, cross-architecture CI, and multiple independent regression paths where subtle defects could cause hangs or CPU-burning behavior.

Grey Divider

Tip of the day
💡 Did you know, you can describe a rule in plain language on the Rules page and Qodo drafts it for you

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment thread src/crates/netipc/src/transport/shm.rs
Comment thread tests/run-rust-shm-timeout-abi.sh Outdated
@ktsaou
ktsaou merged commit 63919ec into main Sep 27, 2026
37 checks passed
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.

3 participants