Skip to content

fix: silence GCC 13 -Wstringop-overflow false positive in native tests - #782

Merged
cb1kenobi merged 1 commit into
mainfrom
fix/gcc13-stringop-overflow-recovery-test
Aug 15, 2026
Merged

fix: silence GCC 13 -Wstringop-overflow false positive in native tests#782
cb1kenobi merged 1 commit into
mainfrom
fix/gcc13-stringop-overflow-recovery-test

Conversation

@cb1kenobi

Copy link
Copy Markdown
Member

Summary

GCC 12/13 (e.g. 13.3.0 on Ubuntu 24.04) emit a -Wstringop-overflow false positive when compiling test/native/transaction_log_recovery_test.cc:

stl_algobase.h:437:30: warning: writing 8 bytes into a region of size 3 [-Wstringop-overflow=]
  inlined from 'void {anonymous}::LogImage::appendF64(double)' at ../test/native/transaction_log_recovery_test.cc:73:15,
  inlined from '{anonymous}::LogImage::LogImage()' at ../test/native/transaction_log_recovery_test.cc:25:12

This is the known GCC 12/13 false-positive family on std::vector<char>::insert(end, ptr, ptr+N) under inlining — the optimizer sizes the copy against the pre-grow capacity. The code is correct; only the diagnostic is wrong.

Fix

Rewrite the three LogImage append helpers (appendU8/appendU32/appendF64) to grow-then-write: resize() the vector, then write directly into bytes.data() + off via the existing rocksdb_js::writeUint8/writeUint32BE/writeDoubleBE helpers. Same bytes produced, but no range-insert for the optimizer to mis-model — more robust than a reserve() workaround, which would only mask this one inline chain.

transaction_log_validation_test.cc has a byte-for-byte identical helper. It happens not to warn today (its constructor takes runtime arguments, which blocks the const-propagation chain), but it gets the same rewrite so the sibling helpers stay consistent and out of this diagnostic family.

Verification

Fresh Ubuntu 24.04 container (podman), g++ 13.3.0-6ubuntu2~24.04.1, Node 24, full node scripts/native-test/run.mjs builds:

Build stringop-overflow Native tests
Pristine main (repro) 1 — exact warning above 104 ran, 103 passed, 1 skipped*
With this fix 0 104 ran, 103 passed, 1 skipped*

* FileLock.SharedHardFailsOnPermissionDenied skips when running as root.

Also verified on macOS (clang): both TUs compile clean, 104 ran, 101 passed + 3 platform-conditional madvise skips.

Pre-existing on main (confirmed at 3ea9a0f), unrelated to #780.

🤖 Generated with Claude Code

GCC 12/13 (e.g. 13.3 on Ubuntu 24.04) emit a -Wstringop-overflow false
positive ('writing 8 bytes into a region of size 3') when inlining
std::vector<char>::insert(end, ptr, ptr+N) through LogImage::appendF64
into the LogImage constructor in transaction_log_recovery_test.cc.
Grow the vector first and write directly into it instead — same bytes,
no range-insert for the optimizer to mis-model.

transaction_log_validation_test.cc has a byte-for-byte identical helper;
it happens not to warn today (its constructor args are runtime values),
but it gets the same rewrite so the sibling helpers stay consistent and
out of this GCC diagnostic family.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@cb1kenobi
cb1kenobi requested a review from kriszyp as a code owner August 14, 2026 22:25

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request refactors the vector insertion logic in transaction_log_recovery_test.cc and transaction_log_validation_test.cc to use a grow-then-write pattern (resize followed by direct write) instead of insert. This change is accompanied by comments explaining that it avoids a GCC 12/13 -Wstringop-overflow false positive. There are no review comments to address, and I have no additional feedback to provide.

@github-actions

Copy link
Copy Markdown
Contributor

📊 Benchmark Results

get-sync.bench.ts

getSync() > random keys - small key size (100 records)

Implementation Rank Operations/sec Mean (ms) Min (ms) Max (ms) RME (%) Samples
🥇 lmdb 1 23.57K ops/sec 42.42 40.87 585.568 0.110 117,875
🥈 rocksdb 2 10.13K ops/sec 98.76 94.33 31,526.357 1.24 50,627

getSync() > sequential keys - small key size (100 records)

Implementation Rank Operations/sec Mean (ms) Min (ms) Max (ms) RME (%) Samples
🥇 lmdb 1 28.43K ops/sec 35.17 33.68 550.505 0.108 142,149
🥈 rocksdb 2 10.66K ops/sec 93.79 88.97 2,470.215 0.107 53,313

ranges.bench.ts

getRange() > small range (100 records, 50 range)

Implementation Rank Operations/sec Mean (ms) Min (ms) Max (ms) RME (%) Samples
🥇 lmdb 1 26.17K ops/sec 38.21 35.57 1,852.963 0.286 130,845
🥈 rocksdb 2 16.14K ops/sec 61.95 52.36 1,082.147 0.126 80,706

realistic-load.bench.ts

Realistic write load with workers > write variable records with transaction log

Implementation Rank Operations/sec Mean (ms) Min (ms) Max (ms) RME (%) Samples
🥇 rocksdb 1 369.06 ops/sec 2,709.565 117.823 48,164.259 14.37 750
🥈 lmdb 2 26.42 ops/sec 37,856.778 390.856 1,178,721.385 135.244 64.00

transaction-log.bench.ts

Transaction log > read 100 iterators while write log with 100 byte records

Implementation Rank Operations/sec Mean (ms) Min (ms) Max (ms) RME (%) Samples
🥇 rocksdb 1 38.80K ops/sec 25.77 12.06 13,751.32 0.579 194,011
🥈 lmdb 2 442.88 ops/sec 2,257.934 260.651 13,631.161 1.31 2,215

Transaction log > read one entry from random position from log with 1000 100 byte records

Implementation Rank Operations/sec Mean (ms) Min (ms) Max (ms) RME (%) Samples
🥇 rocksdb 1 770.48K ops/sec 1.30 1.13 502.688 0.067 3,852,388
🥈 lmdb 2 432.15K ops/sec 2.31 1.10 2,971.676 0.327 2,160,760

worker-put-sync.bench.ts

putSync() > random keys - small key size (100 records, 10 workers)

Implementation Rank Operations/sec Mean (ms) Min (ms) Max (ms) RME (%) Samples
🥇 rocksdb 1 827.98 ops/sec 1,207.762 1,053.281 2,104.34 0.347 1,656
🥈 lmdb 2 1.19 ops/sec 841,630.169 806,397.416 870,583.259 2.04 10.00

worker-transaction-log.bench.ts

Transaction log with workers > write log with 100 byte records

Implementation Rank Operations/sec Mean (ms) Min (ms) Max (ms) RME (%) Samples
🥇 rocksdb 1 22.34K ops/sec 44.76 29.87 521.777 0.572 44,684
🥈 lmdb 2 823.88 ops/sec 1,213.763 308.48 15,371.6 5.29 1,648

Results from commit 40b2704

@cb1kenobi
cb1kenobi merged commit 50da729 into main Aug 15, 2026
26 checks passed
@cb1kenobi
cb1kenobi deleted the fix/gcc13-stringop-overflow-recovery-test branch August 15, 2026 02:57
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.

2 participants